AspectJ creates plenty of methods on pointcut - java

I am new to AOP (using AspectJ / ajc) and have searched / googled the internet high and low searching for an answer to my puzzle. Hopefully, someone here might have it.
As I was given to understand by the documentation, AspectJ is suppose to inject code. From my experience, however, it seems like it is mostly adding code (and simply makes an exchange of method calls).
For example, if I have the method:
private static int foo() {
System.out.println("Hello world");
return 1;
}
And I define the following around advice for it (with a dummy random in order to manipulate proceed() vs. some other return value):
pointcut foo() : call(int com.mytest.aspects.HelloWorld.foo(..));
int around() : foo() {
System.out.println("around()");
if (System.currentTimeMillis() % 2 == 0)
return proceed();
return 0;
}
I get the following after decompiling using jd-gui:
private static final int foo_aroundBody0()
{
return foo();
}
public static void main(String[] args)
{
foo_aroundBody1$advice(HelloAspect.aspectOf(), null);
}
private static final int foo_aroundBody1$advice(HelloAspect ajc$aspectInstance, AroundClosure ajc$aroundClosure)
{
System.out.println("around()");
if (System.currentTimeMillis() % 2L == 0L)
{
AroundClosure localAroundClosure = ajc$aroundClosure;return foo_aroundBody0();
}
return 0;
}
private static int foo()
{
System.out.println("Hello world");
return 1;
}
If that right? Am I perhaps doing something wrong?
I tried using ajc with my android application, but thanks to some jars and SDKs, I got to the dreaded "too many methods" problem.
I am using call pointcuts for most of the time, however it seems that these extra methods are added for each call, even if done within the same class and method, thus increasing my code size and method count significantly.
Any help understanding if this is correct and how it works will be greatly appreciated!

Your understanding is about correct. If you want to avoid too many methods being created, use execution() pointcuts instead of call() wherever possible, because then only one synthetic method per callee will be created, not per caller. I.e. if one method is called from 25 different places, only one additional method will be created instead of 25.
Furthermore you can avoid overhead by limiting the weaving scope of your aspects to the really needed joinpoints. Most aspects I see weave into way too many places. Also, if before() or after() is sufficient, avoid around().

Related

Is there any javadoc tag like "must avoid"?

I am writing a method that is a little overpowered and I want to throw a warning to my user telling him to "better know what you're doing", just like the way #deprecated behaves. I can write this one the method name, but I wonder if there is a more elegant way of doing this.
public class Divison {
public Divison() {
}
private int up;
private int down;
public int eval() {
return ((int) up/down);
}
public void setVars(int up, int down) {
this.up = up;
if (up%down == 0) {
this.down = down;
} else {
throw new ArithmeticException("the values must be divisible");
}
}
public void betterKnowWhatYouDoingSetVars(int up, int down) {
this.up = up;
this.down = down;
}
}
Allowing the outer world to break your invariants is never a good idea, as your class becomes useless: since I can't rely on its internal state being consistent, it's just a bag of values unrelated to each other. To write correct programs, I would need to replicate all your validation logic inline before every usage of that class.
By the way, your example implementation can get in an inconsistent state even without the betterKnowWhatYoureDoing... method, and I'm not even mentioning multi-threading.
You can prevent that by simply making the class immutable and doing that check in the constructor.
I think you should thoroughly re-evaluate your design before going this route.
If you must provide such functionality (I can hardly imagine any reason why), at least make it package-private (instead of public and documented as "dangerous").
Also, those who really know what they're doing are probably never going to call that method anyway, so it's a bit pointless... :)

Is it possible to reinitialize static mutable fields in a class?

I'm trying to automate the testing process for customly written programs designed to solve competitive programming challenges. Below is a dummy sample implementation of Solution:
public class Solution {
private static String dummyField = "initial";
public static int initialize(InputStream in) {
//competitive programmer custom code
System.out.println(dummyField);
dummyField = "changed";
return subCaseCount;
}
public void processSingleSubCase(InputStream in) {
//competitive programmer custom code
}
}
Prewritten test code for solution regardless of its implementation:
public void testSolution() throws FileNotFoundException {
for(File testResource : testResources) {
InputStream in = new FileInputStream(testResource);
int subCaseCount = Foo.initialize(in);
for (int subCase = 0; subCase < subCaseCount; subCase++) {
new Foo().processSingleSubCase(in);
}
//magic call to re-init all static fields without knowing their number/names in advance goes here
}
//console current output:
//initial
//changed
//changed
//...
//desired:
//initial
//initial
//initial
//....
}
The static fields can be mutable, so caching the initial values and mapping them to field names using reflection as a first setup, then reassigning them in between iterations won't do.
I did manage to come up with a working solution which basically reloads the class using a different class loader in between iterations, it did work but was slow: it took about 50 seconds just to reload classes 300 times (test resources are auto generated and I'd like to have the flexibility to auto generate as many as tolerable).
Is there a faster alternative?
My two thoughts for how to do this are:
Use instances rather than statics, since that way the new instance for each test is fresh.
If you need (or want) to stick with statics: Prior to the first test, cache the static values, then reassign them from the cache between tests. If the static values are object references referring to mutable objects, you'll need to make deep copies.

Should exceptions be used to unwinding process back to main?

Now this is really quite difficult for me to explain so please bear with me.
I've been wondering as of late the best way to "unwind" every chained method back to a main method when certain circumstances are met. For example, say I make a call to a method from Main and from that method I call another one and so on. At some point I may want to cancel all further operations of every method that is chained and simply return to the Main method. What is the best way to do this?
I'll give a scenario:
In the following code there are 3 methods, however when Method1 calls Method2 with a null value it should unwind all the way back to Main without further operations in Method2 (EG the "Lots of other code" section).
public static void main(String[] args)
{
try
{
Method1();
}
catch( ReturnToMainException e )
{
// Handle return \\
}
}
public static void Method1() throws ReturnToMainException
{
String someString = null;
Method2( someString );
// Lots more code after here
}
public static boolean Method2( String someString )
{
if( someString == null )
throw new ReturnToMainException();
else if( someString.equals( "Correct" ))
return true;
else
return false;
}
In this example I use a throw which I've read should only be used in "Exceptional Circumstances". I often run into this issue and find myself simply doing If/Else statements to solve the issue, but when dealing with methods that can only return True/False I find I don't have enough options to return to decide on an action. I guess I could use Enumerators or classes but that seems somewhat cumbersome.
I use a throw which I've read should only be used in "Exceptional Circumstances". I often run into this issue and find myself simply doing If/Else statements to solve the issue
Exception throwing is relatively expensive so it should not be used without careful thought but I believe that your example is a ok example of proper usage.
In general, you should use exceptions only for "exceptional" behavior of the program. If someString can be null through some sort of user input, database values, or other normal mechanism then typically you should handle that case with normal return mechanisms if possible.
In your case, you could return a Boolean object (not a primitive) and return null if someString is null.
private static Boolean method2( String someString ) {
if (someString == null) {
return null;
}
...
}
Then you would handle the null appropriately in the caller maybe returning a boolean to main based on whether or not the method "worked".
private static boolean method1() {
...
Boolean result = method2(someString);
if (result == null) {
// the method didn't "work"
return false;
}
Then in main you can see if method1 "worked":
public static void main(String[] args) {
if (!method1()) {
// handle error
}
...
}
Notice that I downcased your method names and changed the permissions of your methods to private both which are good patterns.
Enumerators or classes but that seems somewhat cumbersome.
Yeah indeed. It depends a bit on how this code is used. If it is a API method that is called by others, you might want to return some sort of Result class which might provide feedback like a boolean that the argument was null. Or you might throw an IllegalArgumentException in that case. Instead, if this is an internal local private method, then I'd vote for a simpler way of handling argument errors. Either way I'd use javadocs to document the behavior so you don't trip up future you.
Hope this helps.

Is there a way to test for enum value in a list of candidates? (Java)

This is a simplified example. I have this enum declaration as follows:
public enum ELogLevel {
None,
Debug,
Info,
Error
}
I have this code in another class:
if ((CLog._logLevel == ELogLevel.Info) || (CLog._logLevel == ELogLevel.Debug) || (CLog._logLevel == ELogLevel.Error)) {
System.out.println(formatMessage(message));
}
My question is if there is a way to shorten the test. Ideally i would like somethign to the tune of (this is borrowed from Pascal/Delphi):
if (CLog._logLevel in [ELogLevel.Info, ELogLevel.Debug, ELogLevel.Error])
Instead of the long list of comparisons. Is there such a thing in Java, or maybe a way to achieve it? I am using a trivial example, my intention is to find out if there is a pattern so I can do these types of tests with enum value lists of many more elements.
EDIT: It looks like EnumSet is the closest thing to what I want. The Naïve way of implementing it is via something like:
if (EnumSet.of(ELogLevel.Info, ELogLevel.Debug, ELogLevel.Error).contains(CLog._logLevel))
But under benchmarking, this performs two orders of magnitude slower than the long if/then statement, I guess because the EnumSet is being instantiated every time it runs. This is a problem only for code that runs very often, and even then it's a very minor problem, since over 100M iterations we are talking about 7ms vs 450ms on my box; a very minimal amount of time either way.
What I settled on for code that runs very often is to pre-instantiate the EnumSet in a static variable, and use that instance in the loop, which cuts down the runtime back down to a much more palatable 9ms over 100M iterations.
So it looks like we have a winner! Thanks guys for your quick replies.
what you want is an enum set
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/EnumSet.html
put the elements you want to test for in the set, and then use the Set method contains().
import java.util.EnumSet;
public class EnumSetExample
{
enum Level { NONE, DEBUG, INFO, ERROR };
public static void main(String[] args)
{
EnumSet<Level> subset = EnumSet.of(Level.DEBUG, Level.INFO);
for(Level currentLevel : EnumSet.allOf(Level.class))
{
if (subset.contains(currentLevel))
{
System.out.println("we have " + currentLevel.toString());
}
else
{
System.out.println("we don't have " + currentLevel.toString());
}
}
}
}
There's no way to do it concisely in Java. The closest you can come is to dump the values in a set and call contains(). An EnumSet is probably most efficient in your case. You can shorted the set initialization a little using the double brace idiom, though this has the drawback of creating a new inner class each time you use it, and hence increases the memory usage slightly.
In general, logging levels are implemented as integers:
public static int LEVEL_NONE = 0;
public static int LEVEL_DEBUG = 1;
public static int LEVEL_INFO = 2;
public static int LEVEL_ERROR = 3;
and then you can test for severity using simple comparisons:
if (Clog._loglevel >= LEVEL_DEBUG) {
// log
}
You could use a list of required levels, ie:
List<ELogLevel> levels = Lists.newArrayList(ELogLevel.Info,
ELogLevel.Debug, ELogLevel.Error);
if (levels.contains(CLog._logLevel)) {
//
}

Verifying partially ordered method invocations in JMockit

I'm trying to write a unit test (using JMockit) that verifies that methods are called according to a partial order. The specific use case is ensuring that certain operations are called inside a transaction, but more generally I want to verify something like this:
Method beginTransaction is called.
Methods operation1 through to operationN are called in any order.
Method endTransaction is called.
Method someOtherOperation is called some time before, during or after the transaction.
The Expectations and Verifications APIs don't seem to be able to handle this requirement.
If I have a #Mocked BusinessObject bo I can verify that the right methods are called (in any order) with this:
new Verifications() {{
bo.beginTransaction();
bo.endTransaction();
bo.operation1();
bo.operation2();
bo.someOtherOperation();
}};
optionally making it a FullVerifications to check that there are no other side-effects.
To check the ordering constraints I can do something like this:
new VerificationsInOrder() {{
bo.beginTransaction();
unverifiedInvocations();
bo.endTransaction();
}};
but this does not handle the someOtherOperation case. I can't replace the unverifiedInvocations with bo.operation1(); bo.operation2() because that puts a total ordering on the invocations. A correct implementation of the business method could call bo.operation2(); bo.operation1().
If I make it:
new VerificationsInOrder() {{
unverifiedInvocations();
bo.beginTransaction();
unverifiedInvocations();
bo.endTransaction();
unverifiedInvocations();
}};
then I get a "No unverified invocations left" failure when someOtherOperation is called before the transaction. Trying bo.someOtherOperation(); minTimes = 0 also doesn't work.
So: Is there a clean way to specify partial ordering requirements on method calls using the Expectations/Verifications API in JMockIt? Or do I have to use a MockClass and manually keep track of invocations, a la:
#MockClass(realClass = BusinessObject.class)
public class MockBO {
private boolean op1Called = false;
private boolean op2Called = false;
private boolean beginCalled = false;
#Mock(invocations = 1)
public void operation1() {
op1Called = true;
}
#Mock(invocations = 1)
public void operation2() {
op2Called = true;
}
#Mock(invocations = 1)
public void someOtherOperation() {}
#Mock(invocations = 1)
public void beginTransaction() {
assertFalse(op1Called);
assertFalse(op2Called);
beginCalled = true;
}
#Mock(invocations = 1)
public void endTransaction() {
assertTrue(beginCalled);
assertTrue(op1Called);
assertTrue(op2Called);
}
}
if you really need such test then: don't use mocking library but create your own mock with state inside that can simply check the correct order of methods.
but testing order of invocations is usually a bad sign. my advice would be: don't test it, refactor. you should test your logic and results rather than a sequence of invocations. check if side effects are correct (database content, services interaction etc). if you test the sequence then your test is basically exact copy of your production code. so what's the added value of such test? and such test is also very fragile (as any duplication).
maybe you should make your code looks like that:
beginTransaction()
doTransactionalStuff()
endTransaction()
doNonTransactionalStuff()
From my usage of jmockit, I believe the answer is no even in the latest version 1.49.
You can implement this type of advanced verification using a MockUp extension with some internal fields to keep track of which functions get called, when, and in what order.
For example, I implemented a simple MockUp to track method call counts. The purpose of this example is real, for where the Verifications and Expectations times fields did not work when mocking a ThreadGroup (useful for other sensitive types as well):
public class CalledCheckMockUp<T> extends MockUp<T>
{
private Map<String, Boolean> calledMap = Maps.newHashMap();
private Map<String, AtomicInteger> calledCountMap = Maps.newHashMap();
public void markAsCalled(String methodCalled)
{
if (methodCalled == null)
{
Log.logWarning("Caller attempted to mark a method string" +
" that is null as called, this is surely" +
" either a logic error or an unhandled edge" +
" case.");
}
else
{
calledMap.put(methodCalled, Boolean.TRUE);
calledCountMap.putIfAbsent(methodCalled, new AtomicInteger()).
incrementAndGet();
}
}
public int methodCallCount(String method)
{
return calledCountMap.putIfAbsent(method, new AtomicInteger()).get();
}
public boolean wasMethodCalled(String method)
{
if (method == null)
{
Log.logWarning("Caller attempted to mark a method string" +
" that is null as called, this is surely" +
" either a logic error or an unhandled edge" +
" case.");
return false;
}
return calledMap.containsKey(method) ? calledMap.get(method) :
Boolean.FALSE;
}
}
With usage like the following, where cut1 is a dynamic proxy type that wraps an actual ThreadGroup:
String methodId = "activeCount";
CalledCheckMockUp<ThreadGroup> calledChecker = new CalledCheckMockUp<ThreadGroup>()
{
#Mock
public int activeCount()
{
markAsCalled(methodId);
return active;
}
};
. . .
int callCount = 0;
int activeCount = cut1.activeCount();
callCount += 1;
Assertions.assertTrue(calledChecker.wasMethodCalled(methodId));
Assertions.assertEquals(callCount, calledChecker.methodCallCount(methodId));
I know question is old and this example doesn't fit OP's use case exactly, but hoping it may help guide others to a potential solution that come looking (or the OP, god-forbid this is still unsolved for an important use case, which is unlikely).
Given the complexity of what OP is trying to do, it may help to override the $advice method in your custom MockUp to ease differentiating and recording method calls. Docs here: Applying AOP-style advice.

Categories