Inter Type Declaration on Compiled Class File - aspectj

Is it possible to do Inter Type Declarations with AspectJ on Compiled Class Files at Load Time Weaving?
As an example: I compile some Groovy code and want to add fields or methods with IDT.

Update:
Oh my goodness, you do not need reflection to access members or execute methods. Eclipse shows errors in the editor, but you may just ignore them, the code compiles and runs fine anyway. So the aspect is really much more strightforward and simple:
public aspect LTWAspect {
public static String Application.staticField = "value of static field";
public String Application.normalField = "value of normal field";
public void Application.myMethod() {
System.out.println(normalField);
}
void around() : execution(void Application.main(..)) {
System.out.println("around before");
proceed();
System.out.println("around after");
System.out.println(Application.staticField);
new Application().myMethod();
}
}
Original answer:
Yes, but you have a hen-and-egg problem there, i.e. you cannot just reference the newly introduced fields from your LTW aspect code without reflection. (The last sentence is not true, see update above.) Plus, in order to make your LTW aspect compile, you need the classes to be woven on the project's build path so as to be able to reference them. Example:
Java project
public class Application {
public static void main(String[] args) {
System.out.println("main");
}
}
AspectJ project
import org.aspectj.lang.SoftException;
public aspect LTWAspect {
public static String Application.staticField = "value of static field";
public String Application.normalField = "value of normal field";
public void Application.myMethod() {
try {
System.out.println(Application.class.getDeclaredField("normalField").get(this));
} catch (Exception e) {
throw new SoftException(e);
}
}
void around() : execution(void Application.main(..)) {
System.out.println("around before");
proceed();
System.out.println("around after");
try {
System.out.println(Application.class.getDeclaredField("staticField").get(null));
Application.class.getDeclaredMethod("myMethod", null).invoke(new Application());
} catch (Exception e) {
throw new SoftException(e);
}
}
}
So, e.g. in Eclipse you need to put the Java project on the AspectJ project's build path under "Projects" because only then it can see Java class Application on which you want to declare members. After compilation you just start the Java project and do LTW on the aspect project (don't forget an aop-ajc.xml referencing LTWAspect).
In my example above I declare a static member, a non-static ("normal") member and a non-static method. My advice prints the static member and calls the non-static method, both via reflection. The non-static method then prints the non-static member, again via reflection. This is not nice, but it works and proves the ITD in combination with LTW is possible. There might be a more elegant way, but if so I am unaware of it. (Update: There is a more elegant way: Just ignore the errors marked by Eclipse IDE, see above.)
Program output
around before
main
around after
value of static field
value of normal field

Related

Aspect does not trigger around repositories in my application

I want to trigger my aspect for classes annotated with repositories and belonging to my packages, for example this one:
//com.foo.myapp.bar.repositories.dao
#Repository
public class MyRepo extends JpaRepository<MyEntity, String>{
My classes are jpa repositories created like this:
#EnableTransactionManagement
#EnableJpaRepositories(
entityManagerFactoryRef = "firstManagerFactory",
transactionManagerRef = "firstTransactionManager",
basePackages = {"com.foo.myapp.bar.repositories.first.dao"}
)
public class DbConfig {
My aspect is the following but only activates if I leave the repository() pointcut, but if I also specify application packages it doesn't work:
#Pointcut("within(#org.springframework.stereotype.Repository *)")
private void repositoryInvocation() {
// Method is empty as this is just a Pointcut, the implementations are in the advices.
}
#Pointcut("within(com.foo.myapp..*)")
public void applicationPackage() {
// Method is empty as this is just a Pointcut, the implementations are in the advices.
}
#Around("repositoryInvocation() && applicationPackage()") //this && doesn't work, I have to remove the second one
public Object aspectTriggers(ProceedingJoinPoint joinPoint) throws Throwable {
Object result = joinPoint.proceed();
return result;
}
What am I missing?
edit:
I think I got it: problem is that the implementation of the repository does not belong to my application package, but to spring's SimpleJPARepository. It's like the aspect is only working on the implementation, totally ignoring the interface.
I think you do not want
#Pointcut("within(#org.springframework.stereotype.Repository *)")
but rather
#Pointcut("#within(org.springframework.stereotype.Repository)")
Be careful with your pointcut syntax, the two are not the same:
within() describes a package or class name you want to scope/limit your pointcut to.
#within() looks for a type (class) with the given annotation.
You want the latter, not the former.
Edit: On a second thought, actually I see no obvious reason why the first version should not work, even though it is a bit more complicated than the second.
But you said that you had problems with the second pointcut anyway. Are you 100% sure that your repository class really is in a com.foo.myapp (sub) package? No typo in either the package name or the pointcut? Actually, without trying and only looking at it, it should work otherwise.

org.testng.TestNGException: The following methods have cyclic dependencies while executing tests through TestNG

The Testng exception displays the cyclic dependencies please explain
package test.depends;
import org.testng.annotations.Test
public class SimpleDependencyTes {
#Test
public void testOne() {
System.out.println("The first method");
}
#Test(dependsOnMethods= {"testOne","testTwo"})
public void testTwo() {
System.out.println("The Second method");
}
}
Error is as follows:
org.testng.TestNGException: The following methods have cyclic dependencies:SimpleDependencyTes.testTwo()[pri:0, instance:test.depends.SimpleDependencyTes#1774679]
at org.testng.internal.Graph.topologicalSort(Graph.java:149)
at org.testng.internal.MethodHelper.topologicalSort(MethodHelper.java:261)
at org.testng.internal.MethodHelper.sortMethods(MethodHelper.java:317)
at org.testng.internal.MethodHelper.collectAndOrderMethods(MethodHelper.java:64)
at org.testng.TestRunner.initMethods(TestRunner.java:438)
at org.testng.TestRunner.init(TestRunner.java:271)
at org.testng.TestRunner.init(TestRunner.java:241)
at org.testng.TestRunner.<init>(TestRunner.java:192)
at org.testng.remote.support.RemoteTestNG6_12$1.newTestRunner(RemoteTestNG6_12.java:33)
at org.testng.remote.support.RemoteTestNG6_12$DelegatingTestRunnerFactory.newTestRunner(RemoteTestNG6_12.java:66)
at org.testng.SuiteRunner$ProxyTestRunnerFactory.newTestRunner(SuiteRunner.java:713)
at org.testng.SuiteRunner.init(SuiteRunner.java:260)
at org.testng.SuiteRunner.<init>(SuiteRunner.java:198)
at org.testng.TestNG.createSuiteRunner(TestNG.java:1295)
at org.testng.TestNG.createSuiteRunners(TestNG.java:1273)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1128)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:114)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
Your testTwo lists itself as a dependency:
#Test(dependsOnMethods= {"testOne","testTwo"})
public void testTwo() {
By definition dependsOnMethods means that
(testTwo) will start execution only after all the tests it depends on executed successfully
(source). So if you set testTwo as quoted above, you are saying that testTwo cannot start until testTwo executed successfully. Which is impossible. Instead, you may want to make testTwo dependent on testOne only:
#Test(dependsOnMethods= {"testOne"})
public void testTwo() {
And some other testThree can be dependent on both:
#Test(dependsOnMethods= {"testOne","testTwo"})
public void testThree() {
Circular dependency
Circular dependency is a relation between two or more modules which either directly or indirectly depend on each other to function properly. Such modules are also known as mutually recursive.
Circular dependency can occur in two cases where:
A method testOne() references another method testTwo() and at the same time testTwo() is trying to reference testOne().
A method testTwo() is trying to reference itself i.e. testTwo().
Here you can find a detailed discussion on What is a circular dependency and how can I solve it?
dependsOnMethods
dependsOnMethods is used to create a List of methods on which this method depends on.
dependsOnMethods with #Test annotation
There are two kinds of dependencies:
Hard dependencies: All the methods you depend on must have run and succeeded for you to run. If at least one failure occurred in your dependencies, the method will not be invoked and marked as a SKIP in the report.
Soft dependencies: The method always be run after the methods you depend on, even if some of them have failed. This is useful when you just want to make sure that your test methods are run in a certain order but their success doesn't really depend on the success of others. A soft dependency is obtained by adding "alwaysRun=true" in your #Test annotation.
An example:
#Test
public void initial_test_method() {}
#Test(dependsOnMethods = { "serverStartedOk" })
public void test_method1() {}
In this example, test_method1() is declared as depending on method initial_test_method(), which guarantees that initial_test_method() will always be invoked first.
What went wrong
In your program, the #Test annotation for testTwo() contains testTwo() (itself) as one of the dependsOnMethods. Hence you see the error.
Solution
If you remove the method testTwo() from the List of dependsOnMethods your program will be perfect.
package test.depends;
import org.testng.annotations.Test
public class SimpleDependencyTes {
#Test
public void testOne() {
System.out.println("The first method");
}
#Test(dependsOnMethods= {"testOne"})
public void testTwo() {
System.out.println("The Second method");
}
}
You have defined Dependencies on two method: testOne and testTwo , In which testTwo is itself, Which does not mean. You can not define Dependency on method itself. You can define dependency on any other methods. So you need to remove testTwo dependency.
#Test(dependsOnMethods= {"testOne"})
public void testTwo() {
System.out.println("The Second method");
}
You can define these two dependency for any third #Test method, like:
#Test(dependsOnMethods= {"testOne","testTwo"})
public void testThree() {
System.out.println("The third method");
}

"Signature of the body and declaration in a method implementation do not match"

UPDATE: I think I've eliminated Unity from the equation. See below for more details.
UPDATE 2: I think I may have eliminated Entity Framework fro the equation. See below for more details.
I have some code that is building a unity container, but it started failing with the above error message out of the blue. It works on other people's machines, but not mine. I deleted the folder the solution was in and refreshed everything from source control to ensure I had nothing that could be causing issues (e.g. duplicate assemblies lying around from a previous build).
Here is part of my code:
public static class UnityBootstrapper
{
public static IUnityContainer Initialise()
{
Trace.WriteLine("UnityBootstrapper.Initialise()");
var container = BuildUnityContainer();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
return container;
}
private static IUnityContainer BuildUnityContainer()
{
Trace.WriteLine("UnityBootstrapper.BuildUnityContainer()");
var container = new UnityContainer();
// Other dependencies are registered here
// If the following line is commented out the container is build
// but, obviously, it won't resolve this dependency.
container.RegisterType<IUserAccessEntities, UserAccessEntities>(WebRequestLifetime);
// Other dependencies are registered here
return container;
}
The code apparently fails on the call to BuildUnityContainer(), and I can see that the trace statement I put inside that method is never displayed.
However, if I comment out the line that registers the UserAccessEntities class (which was code generated from Entity Framework 5) then the container is built. Naturally, when I ask for that dependency it can't resolve it, so the code just fails elsewhere.
I've Googled for solutions and they all seem to resolve around generics and moving the generic type from the method to the class level. I can't do that as EF5 creates the class and it puts generics on the properties. e.g
DbSet<MyTable> Tables { get; set; }
The only other thing I can think of is that I've extracted an interface from the EF5 generated class called IUserAccessEntities and the problem could lie there... but I used ReSharper to generate that, so it should be perfectly aligned.
UPDATE
Just to eliminate Unity from the equation, I tried to new up the UserAccessEntities on its own
private static void TestUae()
{
var uae = new UserAccessEntities(); //container.Resolve<IUserAccessEntities>();
Trace.WriteLine("Got the entities: " + uae);
}
And the call to TestUae() fails instead.
UPDATE 2
I created a new class, AlternativeEntities based on the interface I'd previously extracted. When I try to construct that directly it has a new exception: Method 'Set' in type 'AlternativeEntities' from assembly 'UserAccess.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
However, it does. There are two methods called set, both of which I've given a basic implementation:
public class AlternativeEntities : IUserAccessEntities
{
public DbSet<TEntity> Set<TEntity>() where TEntity : class
{
Trace.WriteLine("public DbSet<TEntity> Set<TEntity>() where TEntity : class");
return null;
}
public DbSet Set(Type entityType)
{
Trace.WriteLine("public DbSet Set(Type entityType)");
return null;
}
// Other methods and properties here.
}

Eclipse is forcing everything to be static

For some reason after I had added and removed a static vairable from my code, eclipse started giving me errors on all functions that I call, saying that these functions must be static. However, if I let the program run with these errors, the program runs just as I intended it to do. My Code:
package main;
public class Main implements Runnable {
public void start() {
Thread thread = new Thread(this);
thread.start();
System.out.println("Running...");
Ball.test(); <--- Giving me an error
}
public void run() {
}
public void stop() {
System.out.println("Exiting...");
}
}
and when I create a method in ball called test it gives me:
public static void test() {
// TODO Auto-generated method stub
}
Well yes - you're calling the method as if it were a static method:
Ball.test()
If you want to call an instance method, you need to call it on an instance, e.g.
Ball ball = new Ball();
ball.test();
It's important to understand the difference between static members and instance members. Have you read the appropriate chapter of the Java tutorial? Do you have a good Java book which would help you? (Stack Overflow is great for specific questions, but not good for learning a language from scratch. Explaining language concepts well takes a lot of space and time.)

Linking to GWT instance method from JSNI does not automatically bind "this"

I am going to file this as a bug report, but I wanted to check if someone here can see something wrong with what I am doing.
When you expose an instance method from a GWT class through JSNI, this works as expected in JavaScript. Since we are cross compiling Java, I would instead expect this to be bound to the instance automatically. For example:
package com.test;
class Foo {
public void instanceFunction() {
this.otherFunction() // will cause an error when called from JSNI!
}
public void otherFunction() {
// does some stuff
}
public native JavaScriptObject getInstanceFunction() /*-{
return this.#com.test.Foo::instanceFunction();
}-*/;
}
Currently the workaround is to bind the function yourself (not very portable):
public native JavaScriptObject getInstanceFunction() /*-{
return this.#com.test.Foo::instanceFunction().bind(this);
}-*/;
This can also be seen as preference, some may prefer that the functions remain unbound. I would say the current functionality is unintuitave and unnecessary. I cannot imagine a use case for having an unbound this directly in Java code. Also, some browsers do not implement bind(1), so my workaround is not robust.
If you want a portable bind, it's as easy as:
var that = this;
return $entry(function() {
return that.#com.test.Foo::instanceFunction()();
});