Bug 538411 - [Question] Load classes in runtime after classloader loads it from other jar file
Summary: [Question] Load classes in runtime after classloader loads it from other jar ...
Status: RESOLVED WORKSFORME
Alias: None
Product: AspectJ
Classification: Tools
Component: Runtime (show other bugs)
Version: 1.9.1   Edit
Hardware: PC Windows 10
: P3 normal (vote)
Target Milestone: 1.9.2   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-08-30 08:07 EDT by Alexander Lemyagov CLA
Modified: 2018-10-11 14:23 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alexander Lemyagov CLA 2018-08-30 08:07:51 EDT
I have a programm - .jar. In this programm own classloader. After this jar launched, he load other classes from jars (load plugins).

How i can tell aspectj that he must use loaded classes? 

There is no possibility compile all plugins in one jar.

Thanks.

P.S. I not found place where i can ask a question.
Comment 1 Andrew Clement CLA 2018-08-30 18:40:33 EDT
Not 100% sure I follow the question, but let me talk around what might be the answer.

If you own the classloader you can use it to create a weaver and weave classes. From the docs at:

 https://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html#enabling-load-time-weaving

"A public interface is provided to allow a user written class loader to instantiate a weaver and weave classes after loading and before defining them in the JVM. This enables load-time weaving to be supported in environments where no weaving agent is available. It also allows the user to explicitly restrict by class loader which classes can be woven. For more information, see aj and the API documentation and source for WeavingURLClassLoader and WeavingAdapter."

Or, if you simply run with -javaagent then every classloader will load and get a weaver - the situation you might have then is that you need to configure that weaver. Weavers locate their aop xml files by looking for a resource (META-INF/aop.xml or META-INF/aop-ajc.xml) so you need to have those visible to that weaver (such that they'll be found by a getResources call). The alternative is that you set this property:
-Dorg.aspectj.weaver.loadtime.configuration=file:path/to/a/file/that/defines/weaver/config.xml

Then all weavers created will see that configuration.


As for asking questions, you can use stackoverflow with the aspectj tag or the aspectj user mailing list at https://accounts.eclipse.org/mailing-list/aspectj-users
Comment 2 Alexander Lemyagov CLA 2018-08-31 02:53:19 EDT
(In reply to Andrew Clement from comment #1)
> Not 100% sure I follow the question, but let me talk around what might be
> the answer.
> 
> ...

I have next aop.xml in my jar file. 

<aspectj>
    <aspects>
        <aspect name="com.ua.aspectj.ChameleonAspectLogger"/>
    </aspects>
    <weaver options="-verbose -showWeaveInfo">
        <include within="com.ua.aspectj.*"/>
    </weaver>
</aspectj>

I made own library with aspects and aspectjweaver is cimpiled with my lib. aop.xml contains in my lib. 

Based on your message, I understand that i need put aop.xml in every plugin? 

https://stackoverflow.com/questions/52110010/load-classes-in-runtime-after-classloader-loads-it-from-other-jar-file-aspectj
Comment 3 Alexander Lemyagov CLA 2018-08-31 08:00:03 EDT
maybe this guide help me?
https://www.eclipse.org/aspectj/doc/released/README-187.html
Comment 4 Andrew Clement CLA 2018-08-31 12:28:51 EDT
That stuff in 1.8.7 readme is for dynamically attaching the weaver after startup - if that is your use case, yep use it.  But I guess I don't immediately see why you can't just run with the weaver attached at startup via -javaagent.

Each classloader that will do weaving needs to see an aop.xml file to 'turn it on'. If all your plugins are loaded by one classloader, then you just need one aop.xml file that the classloader managing the plugins can see.  If you have different classloaders for each plugin, then you would need an aop.xml in each plugin. Or you'd set that org.aspectj.weaver.loadtime.configuration that I referred to then all classloaders would pick up the same aop.xml - if there is a subset of loaders you want to be affected rather than all of them (e.g. just use plugin classloaders, take a look at using the property org.aspectj.weaver.loadtime.filter - discussed https://stackoverflow.com/questions/18194719/aspectj-classloading-issue-when-trying-to-use-external-aop-xml-file )
Comment 5 Alexander Lemyagov CLA 2018-09-03 02:09:02 EDT
(In reply to Andrew Clement from comment #4)
> That stuff in 1.8.7 readme is for dynamically attaching the weaver after
> startup - if that is your use case, yep use it.  But I guess I don't
> immediately see why you can't just run with the weaver attached at startup
> via -javaagent.
> 
> Each classloader that will do weaving needs to see an aop.xml file to 'turn
> it on'. If all your plugins are loaded by one classloader, then you just
> need one aop.xml file that the classloader managing the plugins can see.  If
> you have different classloaders for each plugin, then you would need an
> aop.xml in each plugin. Or you'd set that
> org.aspectj.weaver.loadtime.configuration that I referred to then all
> classloaders would pick up the same aop.xml - if there is a subset of
> loaders you want to be affected rather than all of them (e.g. just use
> plugin classloaders, take a look at using the property
> org.aspectj.weaver.loadtime.filter - discussed
> https://stackoverflow.com/questions/18194719/aspectj-classloading-issue-when-
> trying-to-use-external-aop-xml-file )

Thanks for you response.

I try start app with "org.aspectj.weaver.loadtime.configuration", but nothing change. I trying start app with -javaagent, but when classloader load classes aspectj scan packages and found classes in base jar, but not found classes in plugins. AspectJ give message: "[MethodUtil@1bd8afc8] warning at com\ua\aspectj\ChameleonAspectLogger.java::0 no match for this type name: com.pb.chameleon.plugins.print [Xlint:invalidAbsoluteTypeName]"
Comment 6 Alexander Lemyagov CLA 2018-09-03 08:04:22 EDT
(In reply to Andrew Clement from comment #4)
> That stuff in 1.8.7 readme is for dynamically attaching the weaver after
> startup - if that is your use case, yep use it.  But I guess I don't
> immediately see why you can't just run with the weaver attached at startup
> via -javaagent.
> 
> Each classloader that will do weaving needs to see an aop.xml file to 'turn
> it on'. If all your plugins are loaded by one classloader, then you just
> need one aop.xml file that the classloader managing the plugins can see.  If
> you have different classloaders for each plugin, then you would need an
> aop.xml in each plugin. Or you'd set that
> org.aspectj.weaver.loadtime.configuration that I referred to then all
> classloaders would pick up the same aop.xml - if there is a subset of
> loaders you want to be affected rather than all of them (e.g. just use
> plugin classloaders, take a look at using the property
> org.aspectj.weaver.loadtime.filter - discussed
> https://stackoverflow.com/questions/18194719/aspectj-classloading-issue-when-
> trying-to-use-external-aop-xml-file )

I try made example from link and i get this:

java.lang.UnsupportedOperationException: AspectJ weaving agent was neither started via '-javaagent' (preMain) nor attached via 'VirtualMachine.loadAgent' (agentMain).

How fix?
Comment 7 Andrew Clement CLA 2018-09-05 16:58:54 EDT

> I try start app with "org.aspectj.weaver.loadtime.configuration", but nothing change.
> I trying start app with -javaagent, but when classloader load classes aspectj scan packages and found classes in base jar, but not found classes in plugins. AspectJ give message: "[MethodUtil@1bd8afc8] warning at com\ua\aspectj\ChameleonAspectLogger.java::0 no match for this type name: com.pb.chameleon.plugins.print [Xlint:invalidAbsoluteTypeName]"

Doesn't the error just come from weaving in a classloader that you don't care about so you can ignore it?
Unless you specify a filter then all classloaders will get their own weaver - I'd expect the plugin related ones that can see everything to weave ok but others that can only see a piece of the puzzle to produce error messages (like the one you see there).

I don't know enough about your classloader structure.  AspectJ does not do any of its own classloading, instead each weaver defers to the classloader associated with it.

That means if you want a classloader to weave something then the weaver for that loader needs to see the aspects and all dependencies from those aspects, and it will attempt to access all of them through the classloader attached to the weaver. If your classloader is doing regular delegation that means the types need to be visible from the classloader or one of its parents.
Comment 8 Andrew Clement CLA 2018-10-11 14:23:38 EDT
Not sure there is anything to fix here, happy to continue discussion on the mailing list or stackoverflow