Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-users] LTW: Are there any posibilities to avoid using ajc and overcome NoSuchMethodError

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




Back to the top