JAVA : know when a method is called - java

thinking of a weird problem in here. Say for example you have code deployed on your server which does the following:
//GET request called when a URL is hit
public void gETCalled(){
MyClass.invoke();
}
Was wondering if its possible to know, from an external test class (which is deployed in the same server environment) on whether invoke() was ever called at all, without modifying MyClass ?
I am trying to write acceptance tests and was wondering if this was ever possible (without touching my MyClass code)

In terms of test cases, PowerMock can intercept static method calls.
http://code.google.com/p/powermock/wiki/MockStatic
However, from server side code, AoP (in particular aspectj) would be your best bet. That way you don't have to actually change any of your code (just code an aspect class), and you can enable it only when you want to adding in the aspectj weaver as a javaagent.
The aspect would look something like this:
#Aspect
public class TrackMyClassInvoke {
#Before("execution(* MyClass.invoke())")
public void beforeInvoke() {
// do something to track it here
}
}
You'd need to make sure to include MyClass in your weaving (i won't get into the full process of weaving, as you can find that all on the aspectj site)
http://www.eclipse.org/aspectj/

I think you may be able to use AoP to do this. I haven't used it myself, but I believe that it will let you create a logging mechanism where you can do something like when you method is called, print out or log some statement.

Related

How to configure Spring AOP to use AspectJ

I want to use AOP concept to time execution time of some methods that I mark with an annotation that I created. My problem however is that I refer to the annotated method internally, from within the same class. For example:
public void login(params) {
some logic ...
performLogin();
some logic ...
}
#Measured
public void performLogin() {
some logic ...
}
This is a known issue caused by the fact that Spring AOP is using proxy based approach that does not "see" the internal calls within the same class. Apparently I can solve this situation by using AspectJ instead of Spring AOP. If I understand correctly, it can be configured from within Spring itself. From what I found, it looks like I should include #EnableAspectJAutoProxy annotation to configure Spring to use AspectJ instead of its own AOP. Unfortunately, it did not help and after adding the annotation, the interception of the annotated method did not occur.
There is a lot of information on this topic in Spring reference documentation and I got a bit lost. Is there anything else I am supposed to do so that AspectJ will be used?
P.S. Please note that I cannot refactor the whole class and move the calling method outside.
P.P.S. I also verified my pointcut configuration. I annotated the calling method which is invoked externally and it worked fine.
Proxies can only achieve a sub-set of the full capabilities of the actual AspectJ system, basically advice that wraps methods. Due to their nature proxies have following limitations:
interception on external calls only (while breaching proxy boundary)
interception on public members only (private/protected can't be intercepted)
unawareness to local calls (or calls with this or super)
<aop:aspectj-autoproxy /> is not enough - it only wraps methods, you need something like this: <context:load-time-weaver/>
If you want to be able to advise fields for example, you would need to enable the use of Native AspectJ.

Affecting Java classes without changing the code

I am using a Java library, with two classes Foo and FooConfig; I am unable to change the library code, but can read it. Here are the relevant functions of a Foo:
public class Foo
{
/** Install a configuration on this Foo */
void configure(FooConfig config);
/** Uninstall the current configuration */
void unconfigure();
}
The library creates Foos at times I can't control, and installs configurations shortly after creation. A Foo can only have on configuration at a time. I would like to use MyFooConfig, inherited from FooConfig, instead. Is there any way to intercept the configure call, or the FooConfig constructor, or anything like that to use my class instead?
My current solution is to get a reference to the Foo object shortly after its creation and configuration, uninstall the current configuration,and then install a MyFooConfig instead. This could work, but it causes several different problems (both with being a difficult solution to implement and with some inelegancies which can't be hidden from the user). Is there a better way, preferably using features of Java to intercept the constructor call to FooConfig, or the configure method, or something similar? The closest thing to an alternate solution I've found is to try to use a different ClassLoader to replace FooConfig with my own class behind the scenes, but I don't actually have access to the object that creates the FooConfigs so I don't think that's possible. Other things that looked promising but ultimately didn't pan out are proxy objects (I can't make the Foos be proxy objects), seeing if I could somehow get notified when a FooConfig was created without actually intercepting the constructor (so I could find its Foo and reconfigure it in a better way than I`m currently doing), and changing the library code itself (which, for various reasons, turns out to not be possible).
I don't know much about aspect-oriented programming, but it seems like it could help. Unfortunately, all the AOP Java tools seem to require special compilers, and I don't want to change the build process.

Creating our own aspects using custom annotations

I am new to Annotations and new to StackOverflow and this is my first question. I am trying to write custom annotations which will help me trace and log method executions.
For example:
class A
{
#Logthis
void methodA();
}
Here whenever the method methodA() is executed, I want to log to a file telling "we are entering the methodA in class A" and when methodA is over "we are exiting methodA in class A" something like this. We vil have a number of classes and methods.
I know that this can be done using AspectJ. I have done it by defining pointcuts and joinpoints. But I want to do it using custom annotations.
It will be very helpful if anyone can guide me as to how to go about this.
Thanks in advance.
Using AspectJ you do the following :-
Create an Aspect Class annotated with #Aspect
Annotation a method in the class with #Around and define the value to be execution on classes that you have annotated. You will also need to have enabled proxying of you classes by AspectJ.
#Aspect
public class LoggerAspect {
#Around(value = "execution(#you.custom.Annotation * *(..))")
public Object logMethod(ProceedingJoinPoint joinPoint) throws Throwable
{
// DO LOGGING HERE
}
}
You can use Log4J. Here is a tutorial of it:
http://javakane.blogspot.fr/2012/07/automate-log4j-logging-with-aop-and.html
It seems you want to roll your own aop framework. IMHO this is not a very good idea, a lot of work has gone into AspectJ and you would benefit greatly from using it. But I suspect you already know that :) It is strange that you can use NO external jars, that is rather stringent even for commercial software.
But if you really need to do it, you can probably learn from others. AspectJ is open source and there is nothing stopping you from reading through it and adapting it to you needs.
For limited requirements, it is probably not very complex either. You would need a java agent which can look at annotations on classes and methods as they are loaded and modify their bytecode to add logging. Again, there are excellent libraries out there that can aid this but alas you cannot use them.
Another option might be to use jpda. I have no experience with that, but I suspect it will have a significant impact on performance.

Java Intercepting the calls to an Interface Method

I need to intercept the calls to all the method calls to an Interface. I've gone through the Java Dynamic Proxies however that will not help me. I'm not even sure whether this can be achieved, but thought of confirming.
So basically lets say i have an interface as follows:
public interface Foo {
public String getValue();
}
I would like to intercept all the calls to getValue() from whichever implementations of Foo. Problem is i do not have control over the different implementations of Foo, because of which i cant use Dynamic Proxies.
Is there a way i can do this?
Thanks.
AOP might help, but as you've discovered, it all gets much easier if you're in control of the object creation (even if only through a DI framework like Spring or Guice).
Another alternative is compile-time byte-code weaving - that is, finding all implementations and altering them to have your interception code in them at compile time.
A third alternative would be to look at using either an agent or a custom classloader to do weaving as the classes are loaded into the system. This is load-time weaving. But if you're in, say, a web container where you're not fully in charge of the classloaders, this might be tricky.
The only way to do this would be with a custom classloader that replaces the implementation classes with a proxy.
It might be possible to do this out-of-the-box with Spring AOP's load-time weaving.

How to mock a file with EasyMock?

I have recently been introduced to EasyMock and have been asked to develop some unit tests for a FileMonitor class using it. The FileMonitor class is based on a timed event that wakes up and checks for file modification(s) in a defined list of files and directories. I get how to do this using the actual file system, write a test that writes to a file and let the FileMonitor do its thing. So, how do I do this using EasyMock? I just don't get how to have EasyMock mock the file system.
Thanks,
Todd
Something along the lines of:
import static org.easymock.classextension.EasyMock.*;
File testDir = createMock(File.class);
expect(testDir.lastModified()).andReturn(10L);
// more expectations
replay(testDir);
// create a FileMonitor watching testDir
// run the method which gets invoked by the trigger
verify(testDir);
Have a look at the excellent (and concise) user guide. You might reconsider using EasyMock though - most people are currently using or in the process of switching to the more advanced and more actively developed Mockito (inspired by EasyMock).
The basic technique for mocking is to introduce an interface (if the current design doesn't have one) that provides methods for the real service (the dependency) that is being mocked. The test is testing that the class under test interacts correctly with the dependency. Correctly here means that it does what you expect it to do. That does not mean it does the right thing, as the right thing can only be determined by an integration test that uses the real components (what you envision doing by creating a real file).
So you need to have a method on the class under test that lets you pass in an implementation of this interface. The most obvious is via the constructor. You have the production constructor which initializes the class with the real implementation of the interface that hits the real file system, and then under test you pass in the mock to the constructor.
In the test you run the methods on the class and assert that the interface was called in the way you expect.
I will note that coming along after a class is creating and unit testing via mocks is of limited value, but it will help lock down behavior so that future changes to the class won't break expectations in surprising ways.
I hope that helps get you started.
Some mocking frameworks support mocking actual concrete classes, which can make a lot of sense in test-after unit tests (by intercepting calls to real classes not just interfaces). I couldn't find if EasyMock lets you do that, but JDave is probably the place to go if you need that kind of functionality. It even lets you mock final classes.
I would put the actual call to the filesystem in its separate package-private method. For testing, extend the class and override that method. Thus you do not actually make a call to the file system.
EasyMocks classextension has also the possibility to create paritial mocks, but I'm not totally convinced of that.
http://easymock.org/EasyMock2_4_ClassExtension_Documentation.html

Categories