Java - Use annotations and intercept methods? - java

Is there a simple way to intercept methods in java. I need to add an annotation to required methods so that a piece of logic gets called before going through the method.
public void verifyActivity() {
// Asset if you are on a wrong page
}
#VerifyActivity
public void testLogin() {
// Login for my automate test
}
#VerifyActivity
public void testSomethingElse() {
// Test some other UI Automation stuff
}
EDIT:
The recommended guice library for android apps does not contain AOP.
Is it possible to achieve this using reflection without adding any libraries?

Guice provides easy way of implementing annotations. Check this out.
http://code.google.com/p/google-guice/wiki/AOP
http://code.google.com/p/google-guice/

As sid malani said Google Guice is great for this. In general you want to read up on aspect oriented programming tutorials ... There is a nice tool called JMangler that may be of use as well

You can use reflection if you've coded to interfaces through dynamic proxies.

I doubt that it can be nicely done without any 3rd party libs.
There is a library called cglib, which is capable of such things.
Basically it will create a subclass of the intercepted class at runtime. You'll be able to "override" methods by implementing an InvocationHandler, which will act as a proxy when any of the superclass methods being called.

Related

Sending events via code generation with annotations

I have a bunch of methods that must send events when called, i.e. something like this
public void someMethod(){
sendEvent("someMethod was called");
// the method does something
}
public void someOtherMethod(){
sendEvent("someOtherMethod was called");
// the method does something
}
I would like to avoid the sendEvent method call by doing something like
#SendsEvent("someMethod was called")
public void someMethod(){
// do something
}
I have heard of annotation processing as a way of generating code at build time. Would this be possible to do? if so could you point me in the right direction (tutorial or docs).
PS: I have searched on the net for tutorials on annotation processing by they all seem to focus on using the reflections API for runtime annotation processing. This is NOT what I want.
I think for this feature, annotation processing is not worth the additional effort and complexity. Annotation processors are often used for code generation but it doesn't seems you need to generate any dynamic code for this use case. You would have to:
Learn the annotation processor and mirror apis (similar to the reflection api but more complex)
Integrate the processor in your build system
Let the processor generate classes that monitor the annotated methods.
How to do this? There are many ways. You could generate a class that extends your class, adds the event call and then executes the original implementation. Other solution probably involve run-time handling of everything and could be done using reflections
Find a way to load the generated classes instead of you own implementations (DI or something)
Unless you actually really need to generate code for this and do everything at compile time, you should probably just do everything at runtime when the application starts. Checking for annotations once in the beginning using reflections should not impact performance in any way. Use a Proxy to intercept method invocations and add your event calls.

Implementing an interface from a framework vs simple java interface

This concept is unclear with me.
I have worked on several frameworks for an instance Spring.
To implement a feature we always implement some interfaces provided by the framework.
For an instance if I have to create a custom scope in Spring, my class implements a org.springframework.beans.factory.config.Scope interface. Which has some predefined low level functionality which helps in defining a custom scope for a bean.
Whereas in Java I read an interface is just a declaration which classes can implement & define their own functionality. The methods of an interface have no predefined functionality.
interface Car
{
topSpeed();
acclerate();
deaccelrate();
}
The methods here don't have any functionality. They are just declared.
Can anyone explain this discrepancy in the concept? How does the framework put some predefined functionality with interface methods?
It doesn't put predefined functionality in the methods. But when you implement
some interface (say I) in your class C, the framework knows that your object (of type C)
implements the I interface, and can call certain methods (defined in I) on your object
thus sending some signals/events to your object. These events can be e.g. 'app initialized',
'app started', 'app stopped', 'app destroyed'. So usually this is what frameworks do.
I am talking about frameworks in general here, not Spring in particular.
There is no conceptual difference, actually. Each java interface method has a very clear responsibility (usually described in its javadoc). Take Collection.size() as an example. It is defined to return the number of elements in your collection. Having it return a random number is possible, but will cause no end of grief for any caller. Interface methods have defined semantics ;)
As I mentioned in the comments, to some extent, implementing interfaces provided by the framework is replaced by the use of stereotype annotations. For example, you might annotate a class as #Entity to let Spring know to manage it and weave a Transaction manager into it.
I have a suspicion that what you are seeing relates to how Spring and other frameworks make use of dynamic proxies to inject functionality.
For an example of Spring injecting functionality, if you annotate a method as #Transactional, then the framework will attempt to create a dynamic proxy, which wraps access to your method. i.e. When something calls your "save()" method, the call is actually to the proxy, which might do things like starting a transaction before passing the call to your implementation, and then closing the transaction after your method has completed.
Spring is able to do this at runtime if you have defined an interface, because it is able to create a dynamic proxy which implements the same interface as your class. So where you have:
#Autowired
MyServiceInterface myService;
That is injected with SpringDynamicProxyToMyServiceImpl instead of MyServiceImpl.
However, with Spring you may have noticed that you don't always need to use interfaces. This is because it also permits AspectJ compile-time weaving. Using AspectJ actually injects the functionality into your class at compile-time, so that you are no longer forced to use an interface and implementation. You can read more about Spring AOP here:
http://docs.spring.io/spring/docs/4.0.0.RELEASE/spring-framework-reference/htmlsingle/#aop-introduction-defn
I should point out that although Spring does generally enable you to avoid defining both interface and implementation for your beans, it's not such a good idea to take advantage of it. Using separate interface and implementation is very valuable for unit testing, as it enables you to do things like inject a stub which implements an interface, instead of a full-blown implementation of something which needs database access and other rich functionality.

Easily switching between two different implementations of a java library?

I am currently working on a project that uses a third party library to manage hardware.
I wish to create a substitute library that presents the same interface, but instead of controlling actual hardware just presents a nice fake GUI. Preferably this can be done just by replacing the jar.
The problem is that all of the third party code is in the namespace edu.edu.wpi.first.wpilibj, and of course the namespace for my library is going to be very different.
Is there any way of easily switching implementations between the two libraries providing the same interface in java?
Yes, there are design patterns to do that.
You can look into Strategy pattern.
Even better you can look into Dependency injection.
You can use Google Guice as container and based on your configuration, at runtime, your implementation can switch between using N libraries.
At the end of the day, you need to wrap those libraries around some abstraction.
here is an example:
interface ISomeOperation{
void process();
}
class ThatUsesTheWPILIBJ implements ISomeOperation{
void process(){
//use library here
}
}
class ThatUsesYourMock implements ISomeOperation{
void process(){
//use your mock here
}
}
public YourUIClass{
private ISomeOperation _operatingClass;
public YourUIClass(ISomeOperation operatingClass){
_operatingClass = operatingClass;
}
public void render(){
_operatingClass.process();
}
}
Now all you need to do is wiring. Look at google guice configuraion.
Yes. ServiceLoader.
It allows to switch implementations by puting jar in classpath (or by some configuration).
But it does not help with existing code. (But once done, switching to any other implementation is easy.
Its easy to library that uses it, but if library does not use it, it can be hard to introduce service loading. You would need to create service-loading wrapper. And if another library uses the original library, you would need to change and recompile it too.
Another approach would be puting it in same package as original library and mirror its public interface. But that is ugly.

Java annoations

I used a lot annotations in java but I never wrote one. I read though several guides and I am really confused.
They are using annotations like meta information eg names, age etc. That is really confusing because I want to do something different
http://www.developer.com/java/other/article.php/3556176/An-Introduction-to-Java-Annotations.htm
I want to control the function calls.
for example
#Permission(user)
public static void account(){
...
}
So my functions only gets called if the user has the permission, otherwise the user should be redirected to the login page.
I could not find any information, maybe I am using the wrong keyword?
I hope you can clear things up,
Thanks.
You can do that, but with a lot of extra code. Intercepting method calls is part of AOP (aspect oriented programming). You need to make proxies of you target objects, and in the invocation handler parse the annotation.
Luckily, you don't have to do that - since you have a webapp, just use spring/spring-mvc/spring-security. Spring gives you an AOP framework that you can use to define aspects handling your permission logic
Not sure how you can do this by yourself but if you are using Spring they have something that may help
http://static.springsource.org/spring-security/site/docs/3.0.7.RELEASE/reference/el-access.html
I use it my current project and it works well
Something like that should really be done in the function itself (or in some other part of the program). Note that annotations provide data about a program that is not part of the program itself (see this reference).
I think what you are after is an AOP advisor which is run before your method. See here: http://java-questions.com/spring_aop.html
As an alternative to Spring, you could use AspectJ: http://www.andrewewhite.net/wordpress/2010/03/17/aspectj-annotation-tutorial/

Is it possible to monkey patch in Java?

I don't want to discuss the merits of this approach, just if it is possible. I believe the answer to be "no". But maybe someone will surprise me!
Imagine you have a core widget class. It has a method calculateHeight(), that returns a height. The height is too big - this result in buttons (say) that are too big. You can extend DefaultWidget to create your own NiceWidget, and implement your own calculateHeight() to return a nicer size.
Now a library class WindowDisplayFactory, instantiates DefaultWidget in a fairly complex method. You would like it to use your NiceWidget. The factory class's method looks something like this:
public IWidget createView(Component parent) {
DefaultWidget widget = new DefaultWidget(CONSTS.BLUE, CONSTS.SIZE_STUPIDLY);
// bunch of ifs ...
SomeOtherWidget bla = new SomeOtherWidget(widget);
SomeResultWidget result = new SomeResultWidget(parent);
SomeListener listener = new SomeListener(parent, widget, flags);
// more widget creation and voodoo here
return result;
}
That's the deal. The result has the DefaultWidget deep within a hierarchy of other objects. The question - how to get this factory method to use my own NiceWidget? Or at least get my own calculateHeight() in there. Ideally, I'd like to be able to monkey patch the DefaultWidget so that its calculateHeight did the right thing...
public class MyWindowDisplayFactory {
public IWidget createView(Component parent) {
DefaultWidget.class.setMethod("calculateHeight", myCalculateHeight);
return super.createView(parent);
}
}
Which is what I could do in Python, Ruby, etc. I've invented the name setMethod() though. The other options open to me are:
Copying and pasting the code of the createView() method into my own class that inherits from the factory class
Living with widgets that are too big
The factory class can't be changed - it is part of a core platform API. I tried reflection on the returned result to get to the widget that (eventually) got added, but it is several widget-layers down and somewhere it gets used to initialize other stuff, causing odd side effects.
Any ideas? My solution so far is the copy-paste job, but that's a cop out that requires tracking the changes in the parent factory class when upgrading to newer versions of the platform, and I'd be interested to hear other options.
Perhaps you could use Aspect Oriented Programming to trap calls to that function and return your own version instead?
Spring offers some AOP functionality but there are other libraries that do it as well.
One ugly solution would be to put your own implementation of DefaultWidget (with same FQCN) earlier on the Classpath than the normal implementation. It's a terrible hack, but every other approach that I can think of is even worse.
Just my concept idea,
It is possible that use AOP, with bytecode engineering way, to inject a aspect to the calculateHeight method.
Then, you may enable you patch by ThreadLocal or else variable.
cglib is a Java library that can do some things similar to monkey patching - it can manipulate bytecode at runtime to change certain behaviours. I'm not sure if it can do exactly what you need, but it's worth a look...
It is totally possible to monkeypatch in Java, using Unsafe.putObject and a class finder. Wrote a blog post here:
https://tersesystems.com/blog/2014/03/02/monkeypatching-java-classes/
The object-oriented way of doing this would be to create a wrapper implementing IWidget, delegating all calls to the actual widget, except calculateHeight, something like:
class MyWidget implements IWidget {
private IWidget delegate;
public MyWidget(IWidget d) {
this.delegate = d;
}
public int calculateHeight() {
// my implementation of calculate height
}
// for all other methods: {
public Object foo(Object bar) {
return delegate.foo(bar);
}
}
For this to work, you need to intercept all creations of the widget you want to replace, which probably means creating a similar wrapper for the WidgetFactory. And you must be able to configure which WidgetFactory to use.
It also depends on no client trying to cast the IWidget back to DefaultWidget...
Only suggestions I can think of:
Dig through the library API to see if there's some way of overriding the defaults and sizing. Sizing can be confusing in swing (at least to me) , setMinimum, setMaximum, setdefault, setDefaultOnThursday, ... . It's possible there's a way. If you can contact the library designer(s) you might find an answer that will alleviate the need for unpleasant hacking.
Perhaps extend the factory only overriding some default sizing parameter? depends on the factory but it might be possible.
Creating a class with the same name might be the only other option, as others have pointed out it's ugly and you're liable to forget it and break stuff when you update the api library or deploy in a different environment and forget why you had the classpath set up that way.
You can try using tools like PowerMock/Mockito. If you can mock in tests, you can mock in production too.
However these tools are not really designed to be used that way, so you'll have to prepare the environment yourself and won't be able to use the JUnit runners like you do in tests...
Well, I keep trying to post suggestions, and then I see that they won't work or that you've already mentioned you tried them.
The best solution I can think of is to subclass WindowDisplayFactory, then in the subclass's createView() method, first call super.createView(), then modify the object returned to completely throw out the widget and replace it with an instance of the subclass that does what you want. But the widget is used to initialize stuff, so you'd have to go change all of those.
Then I think of using reflection on the returned object from createView() and trying to fix things up that way, but again, that's hairy because so much stuff was initialized with the widget. I think I would try to use that approach, though, if it was simple enough to justify it over copying and pasting.
I'll be watching this, plus thinking to see if I can come up with any other ideas. Java Reflection sure is nice, but it can't beat the dynamic introspection I've seen available in languages such as Perl and Python.

Categories

Resources