Hi,
My project uses a custom plugin framework, where plugin's are JAR files loaded at run-time by the framework using custom class loader. We have several plugin JAR files that are to be loaded and AOP looks to be a perfect solution to add a particular functionality across plugins.
Following are my Aspect definition and other implementation details:
package net.XXX.pub.plugin;
@Aspect
public class
FatalWarningAdvice
{
@Around("target(net.XXX.pub.plugin.XXX.XXModelSerializable) && call(@ReportFatalError * *(..))")
public void handleFatalWarning(ProceedingJoinPoint joinPoint) throws Throwable {
XXModelSerializable target = (XXModelSerializable)joinPoint.getTarget();
try {
joinPoint.proceed();
} catch(Throwable ex) {
throw new
XXPluginException(target.getDetailedErrorMessage(ex));
}
}
/* Adding below method solves my problem, but are there any better way to solve this problem ?
public static FatalWarningAdvice aspectOf() {
return new
FatalWarningAdvice();
}*/
}
The above aspect is part of public.jar file. I have also defined aop.xml file under META-INF folder as follows:
<aspectj>
<aspects>
<!-- declare existing aspects to the weaver -->
<aspect name="net.XXX.pub.plugin.FatalWarningAdvice"/>
</aspects>
<weaver options="-showWeaveInfo">
<include within="com.XXX.plugin..*"/>
<include within="net.XXX.pub.plugin..*"/>
</weaver>
</aspectj>
I want FatalWarningAdvice aspect to be weaved on runtime when plugin's are loaded by the plugin framework. Following code demonstrated the same:
private synchronized ClassLoader getClassLoader(String jarName) throws IOException {
ClassLoader classLoader = classLoaders.get(jarName);
if(null == classLoader) {
ClassLoader startupClassLoader =
PluginServiceImpl.class.getClassLoader();
File jarFile = new File(runtimeJarDir, jarName);
File aspectJarFile = new File("public.jar");
//classLoader = new NestedJarClassLoader(jarFile, tmpJarDir, startupClassLoader);
//Below call provides list of URLs that will be input to AspectJ weaver.
List<URL> classURLs = NestedJarClassLoader.getURLList(jarFile,
tmpJarDir);
classURLs.add(aspectJarFile.toURI().toURL());
classLoader = new WeavingURLClassLoader(classURLs.toArray(new URL[classURLs.size()]), new URL[]{aspectJarFile.toURI().toURL()}, startupClassLoader);
classLoaders.put(jarName, classLoader);
}
return classLoader;
}
Upon executing the above code
I get the following exception:
java.lang.NoSuchMethodError: net.XXX.pub.plugin.FatalWarningAdvice.aspectOf()Lnet/XXX/pub/plugin/FatalWarningAdvice;
I could temporarily over come this problem by adding below lines of code in my Aspect:
public static FatalWarningAdvice aspectOf() {
return new FatalWarningAdvice();
}
Are there any work-around to this problem ? One solution is to use ajc or iajc but then I requires change to my build environment. As part of LTW are there any possibility to avoid using ajc ?
Introducing ajc in the build process is a pain as it will affect the team, each developer has to include the aspectj-tools.jar to ant library (to my knowledge). Are there any possibilities for AspectJ to include these methods at runtime ?
Thanks in advance
Gokul