Using Otto, method only subscribes if I call it directly elsewhere - java

I have an issue where one of my subscribed methods does not get called upon a post of the correct event type unless that subscribed method is used (called) elsewhere.
Here is some relevant information about the code:
A method of one of my classes is annotated with #Subscribe.
By stepping through the code with the debugger, I find that under my specific circumstance, the class has no methods annotated with #Subscribe.
Unless I call the method directly at some point in time (doesn't matter when, or even if it actually gets called at runtime) elsewhere, my post does not work.
The IDE (Android Studio) notifies me that the "method is never used"
I can certainly call the method in a block of code that I am confident will never fire, but this is obviously terrible practice, and defeats the purpose of this post/subscribe paradigm.
Or I can make the method static, but I'd rather not because I use member variables inside of it.
Any solutions to why this is occuring even though Otto's example uses a similar pattern

Turns out it was a ProGuard issue. Fixed it by adding the following lines:
-keepclassmembers class ** {
#com.squareup.otto.Subscribe public *;
#com.squareup.otto.Produce public *;
}

Related

Force a dependency's class to be loaded, without explicitly referencing it in code?

Let's say I have a class which looks like this:
public class Initializer {
static { /* a bunch of stuff happens here that's useful */ }
}
basically it registers a bunch of other classes in a lookup table; it's connected to an annotation processor. Is it a weird design? I don't know, I don't have a good point of reference, I didn't write it, it's just how it is. If this class is loaded, then the initialization happens and we're good, and if it isn't, we're not good.
The problem is, there's no normal reason you would ever refer to this class, so the "normal" way you would make sure this class gets loaded is to execute Class.forName("a.b.c.Initializer"); somewhere in your app's initialization logic. That's not hard to do (I think SQL drivers are initialized similarly, unless they're wrapped in a helper function call).
But unfortunately it is sort of a strange step, and it's easy to forget, and it has opaque errors. Outside of providing a nicely named helper function MyLibrary.initialize() so you don't have to do an arcane Class.forName("darkest.magic") call, is there a way to make this completely automatic?
For instance, is there a way to either
Somehow rig up in the build.gradle file (of the package that needs initializing, or less desirably, the downstream package that uses it) that this class needs to be loaded?
Somehow set up code that must be run when this package is loaded?
Would appreciate any suggestions or workarounds so that users don't have to explicitly initialize "my" library. Thanks.

which object method of interface implementation will be called

I have a code like below in project. Here by casting with interface we are calling the method authenticate() of the service IAuthenticateService. Now there are 5 subclasses which have the same method implementation and Implementing the same interface IAuthenticateService. By seeing the code how will I come to know which class method implementation has been called? I'm little bit confused of interface design.
((IAuthenticateService) AuthServiceApp.getInstance().getContext()
.getService(ServiceEnum.CredentialService.name()))
.authenticate(inputParams);
You can't know just by reading this code.
But, the program will know at runtime which implementation to call : the object returned by AuthServiceApp.getInstance().getContext() will have a type, which one will have a single implementation of the method getService, and this implementation will be called.
As a programmer, you don't need to know more. The programming by contract paradigm allows you not to bother about which implementation will be called. All you need to know is that given a certain environment, you will get an instance of a context on which you can call getService(), AND it will provide you with a service.
The rest is details, you don't have to worry about it.
Of course, when you are debugging, that's a different story : you want to know which implementation is executed as it might be buggy. In that case, just follow the debugger to see which code is really executed, but otherwise, you should not care, that's all what polymorphism is about : gaining abstraction.
Well you not being able to tell what implementation of IAuthentication is being returned is the whole point of interfaces. We use interfaces to segment parts of code away from each other. This makes programs more extensible and versatile which drives code reuse. It is a very powerful concept and the corner stone of modern software development. The client (the code using the interface's methods) does not care what is on the other side of the interface (ie the implementer of the interface). This allows for the client side to change at runtime. The fact that you don't know is what gives its power. In order to understand this concept you have to think about how the compiler works and what it does when it compiles code.
In compiled languages the compiler translates source code into machine instructions. When it is translating a method into a machine code the method receives an address in memory where the method starts. When another piece of code calls that method that memory address is written in the code on the client code. That memory address is fixed so that piece of code can't call any other method at runtime. It will always call that one method and never a different method.
For example say we have something like this:
private int someMethod() { ... }
The compiler says someMethod is located at 003. So when it's compiling code like this:
public myMethod() {
this.someMethod();
}
It says myMethod calls someMethod, and looks up where in memory someMethod lives. Roughly it will write out something like:
// myMethod
call 003
Now that method invocation (aka call site) can only ever call someMethod forever. It will never call any other method but that exact method.
But in OO languages we can vary which actual method is called at runtime. That means the compiler can't write that memory address into the callers code when it is compiling the class. Instead it has to look up that method address at runtime. How it does that is by looking up the method by name in the object it is passed at runtime. So the compiler might do something like this:
// myMethod
methodAddress = this.methodsAddresses['someMethod']
call methodAddress
It's that lookup (sometimes called the virtual pointer table) that enables methods to change depending on what someObject points to, and that lookup allows it to vary at runtime.
This is all well and good until you need to debug something. If you are trying to debug something its easiest if you use a debugger, and drop a break point in your client code and you can easily look at that an many other things along with stepping into the code. You can also print someObject.getClass().getName() to find the name, but that is just the beginning if you are debugging.

Proguard keepclassmembers keeps class

Sorry if I've missed a response that would cover this, but I've tried to be diligent about finding anything similar.
I'm really confused by Proguard's behaviour, and I'm wondering if I'm reading the docs wrong or if the behaviour is wrong.
I want to retain annotated fields and members in a class, if that class is kept. So I used keepclassmembers like so:
-keepclassmembers class com.mycompany.** {
#com.mycompany.**
public com.mycompany.** *;
#com.mycompany.**
public void *(com.mycompany.**);
}
(This configuration was built by the GUI, but I think I see what it's doing.) The Proguard docs say
-keepclassmembers [,modifier,...] class_specification
Specifies class members to be preserved, if their classes are preserved as well. For example, you may want to keep all serialization fields and methods of classes that implement the Serializable interface.
Sounds good. But I'm getting classes I don't expect in the output, just because they have #annotated listeners. -whyareyoukeeping class com.company.MyServiceImpl?
com.mycompany.MyServiceImpl
is invoked by com.mycompany.MyServiceImpl: void handleEvent(com.mycompany.MyEvent) (34:35)
is kept by a directive in the configuration.
handleEvent just calls another method in MyServiceImpl, so it doesn't seem to be a valid reason to keep the whole class, but that's the only think I can think of.
Why does keepclassmembers appear to force keep on any class containing a specified member, not only "if their classes are preserved as well"? But more directly, how can I keep public annotated event listeners in classes that Proguard is already keeping via other rules?
Your initial configuration and interpretation of it look correct. It also works if I try it on a simple example: annotated fields and methods are kept if their classes are already kept. Of course, those annotated methods may contain code that drags in more classes.
The output of -whyareyoukeeping only tells half the story and isn't very helpful in this case. You could check if -printseeds provides some hints.
The workable configuration with 'allow' modifiers doesn't seem to make much sense; I wouldn't trust it too much.
If you still think there is a bug, you can report it in the ProGuard bug tracker, preferably with an example that allows me to reproduce the problem.

About #override annotation in Activity callbacks

It seems in an Activity, for example, the onCreate() method, it does not make much difference if I have the #Override annotation or not. They both work. (As long as I call super.onCreate() inside the callback , it will call the parent class' method.)
Can someone tell me why we need to have the #Override annotation for life-cycle callbacks in Activity ?
I ask this because I tested without #Override annotation, my app still running successfully.
This is more like a good development practice.
If by mistake you want to override a method that doesn't exist in the super class (or interfaces implemented) you'll get an error.
Think that you want to override "onCreate" but you misspell it and write "onCreatee". With that annotation, you'll get an error. Without it, you'd end up spend a lot time trying to understand why your initialization method was not working properly.
The #Override annotation is used just to tell the compiler that we are overriding a method in our code. This is used for safety purposes to let the compiler know the aim of our function (i.e. to override) and if we are overloading a function by any chance, the compiler will return an error. Hence with this annotation, we can detect overloading mistakes easily.
Some already mentioned that it is very useful to catch potential bugs with wrongly spelled names.
I would like to add that it
also shows which methods are new methods specific to your class and which are inherited from the parent class (or interface). It might not sound like much, but I personally find it very useful.
So you should always use #Override and configure your IDE to flag an error if you forget it.

How to test an anonymous inner class that calls a private method

We have a bunch of classes that listen for events from the server and then respond to them. For example:
class EventManager {
private Set<Event> cache = new HashSet<Event>();
private EventListener eventListener = new EventListener() {
void onEvent(Event e) {
if (e instanceof MyEvent || e instanceof YourEvent) {
handleEvent(e);
}
}
}
public EventManager(ServerCommunication serverComm) {
serverComm.addListener(eventListener);
}
private handleEvent(Event e) {
// handle the event...
// ...
cache.add(cache);
// ...
}
}
Here's a made-up example of the kind of thing we are doing. Here are the problems I see:
I'd like to test handleEvent to make sure it's doing what it is supposed to but I can't because it's private.
I'd also like to check that something got added to the cache too but that also seems difficult since cache is a private member and I don't want to add a needless getter method.
I'd also like to test the code inside the anonymous class's onEvent method.
For now, what I did was move all logic from the anonymous class to the handleEvent method, and I made handleEvent package private (my unit test is in the same package). I'm not checking the contents of the cache although I want to.
Does anyone have any suggestion for a better design that is more testable?
I would probably extract a EventCache component. You can replace this for your test with an implementation that counts the cached events or records whatever is of interest.
I probably would not change the visibility of handleEvent. You could implement a ServerCommunication that just raises the event from the test case.
Well, there are two approaches here: black box and white box.
Black box testing suggests you should only test the publicly visible changes. Does this method have any observable effect? (Some things don't - caches being an obvious example where they improve performance but may otherwise be invisible.) If so, test that. If not, test that it isn't having a negative effect - this may well just be a case of beefing up other tests.
White box testing suggests that maybe you could add a package-level method for the sake of testing, e.g.
Cache getCacheForTesting()
By putting "for testing" in the name, you're making it obvious to everyone that they shouldn't call this from production code. You could use an annotation to indicate the same thing, and perhaps even have some build rules to make sure that nothing from production does call such a method.
This ends up being more brittle - more tied to the implementation - but it does make it easier to test the code thoroughly, IMO. Personally I err on the side of white box testing for unit tests, whereas integration tests should definitely be more black box. Others are rather more dogmatic about only testing the public API.
I assume your EventManager is a singleton, or you have access to the particular instance of the class you're testing.
1 - I suppose you can send events to your class. Your method is private, and nobody else can call it, then sending an event should be enough.
2 - You can access that through reflection, if you really need to. Your test would depend on a particular implementation.
3 - What would you like to test, actually? If you want to be sure that this method is called, you can replace the EventListener with another EventListener object through reflection (and eventually call the onEvent method of the first listener from your new listener). But your question seems to be more about code coverage than actual unit-testing.
Sometimes, when coming across private methods that I want to test... they are simply screaming to be public methods on another object.
If you believe that HandleEvent is worth testing in isolation (and not through onEvent processing), one approach would be to expose HandleEvent as a public method on new/different object.
Use this opportunity to break the code up into smaller more focussed (default access) classes. A test is just another client for the code.
Note that the anonymous inner class' onEvent method is actually accessible, so calling it should not be a problem.

Categories

Resources