Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] How to advise already loaded classes using LTW?

So I updated my pointcut to try to advise my EJBs directly (instead of trying to advise the container's authorization interceptor), but I'm not having success. 

JBoss' own aspect/interceptor seems to be taking precedence over my own pointcut, which I find hard to explain, and the JBoss aspect is firing instead of my own.

This is my aspect definition:
@Pointcut("call( @(javax.annotation.security..*) * *.*(..))")
public void securedEJB(){}
@Around( "securedEJB()" )
public Object logEJBAccess( ProceedingJoinPoint pjp ) throws Throwable{
logger.warn("EJB CHECK HERE!!!!!!!!!!!");
Object o = null;
try {
o = pjp.proceed();
} catch (Throwable e) {
logger.error("EJB Threw Exception " + e );
e.printStackTrace();
throw e;
}
return o;
}


Yet, for all my secured EJB methods, I get the JBoss aspect that is checking for security rights prior to my own calls to method and hence this advice is never ever run.

An example of a call is:

OrganizationManager om = (OrganizationManager)SessionBeanLocator.getSessionBean(OrganizationManager.class);
om.getThirdPartyOrgsForLogin( "asdf", null );
System.out.println( "OM" + om );

Where OM is the interface to the EJB bean:

   @PermitAll
   @TransactionAttribute(TransactionAttributeType.NEVER)
   public List getThirdPartyOrgsForLogin(String username, BusinessContextInfo contextInfo) throws IzoneBusinessException {
   ...
   ...
   }


Any ideas what I can do?

Thanks,

Eric






On Sun, Aug 21, 2016 at 10:14 PM, Eric B <ebenzacar@xxxxxxxxx> wrote:
Hi Alex,

You're right.  There is no real reason other than laziness to try to advise container classes.  I'm actually trying to log EJB authorization, so instead of advising every EJB method, I was thinking of advising the container's authorization interceptor and checking if the interceptor throws an exception.  I guess the non-lazy (proper ?:)) way is to advise all secured EJB methods.   I'll have to give that a shot tomorrow.  But it just made me think/wonder if there was any way to advise classes that were already loaded.

It also doesn't address my issue when I am trying to LTW classes that are only visible to the child classloader but not the classloader that loaded the apsects.  Which means that I still don't know how to access the advised parameters/return values.

Any thoughts which flags I should use to get the most info out of the advise process?  I have the verbose flag enabled in my aop.xml, but it doesn't seem to give me enough details.  I know I get more details out when using CTW with ajc, but I suspect that is because it knows exactly which methods it can match on compile, vs LTW when it never knows if it matches or not until the classes are loaded.  So you never get warnings that pointcuts don't match.

Thanks!

Eric


On Sun, Aug 21, 2016 at 5:17 PM, Alexander Kriegisch <alexander@xxxxxxxxxxxxxx> wrote:
Hi Eric.

I do not really want to imagine what makes you think you need/want to advise container classes. I would assume that there must be a better way to technically achieve what you want. You said the problem was about the legacy application, not about the container.

Anyway, for what it is worth, in principal you can, if you can influence how the container is started, apply binary weaving to container classes and put aspectjrt.jar on the JVM boot classpath. As for the third party library (Struts), it would be interesting to find out what causes the class visibility problem you mentioned. But even if you do not find out, you can still apply binary weaving to all JARs in your EAR, repackage the woven version and also use it in connection with aspectjrt.jar. No LTW means no LTW-related problems.

I am pretty sure there also is a way to fix the LTW situation, but I can only speculate about it because I am not really a container champion. Maybe if I had the binaries and exact setup to locally reproduce the problem... Maybe you can find out more by setting the appropriate debug logging options in your container as well as in AspectJ itself.

As for retransforming already loaded classes, I once tried but failed because either it is not possible or just because I do not know enough about the JVM. In order to manually handle that.

As I said: if I were you I would try to reduce the situation's complexity by using binary weaving instead of LTW. Just my two cents. Probably Andy has a much better answer for you, as usual. :-)

Regards
-- 
Alexander Kriegisch


Am 21.08.2016 um 23:01 schrieb Eric B <ebenzacar@xxxxxxxxx>:

Hi Alex,

Actually, there are some struts classes I want to advise.  But I have 2 issues (related but distinct) with approach #1.

1) I an able to advise the struts classes, but cannot use any of the struts class definitions as they are not exposed to the aspect.  That means if I was to access any arguments that are struts classes (parameters or return values) as anything more than mere Object,  I can't.  I get ClassDefNotFound exceptions.

2) I would like to advise some container (JEE) classes, but they aren't advisable either as they have already been loaded by then time the container loads my aspect jar.

I haven't actually tried using call() instead of execution() yet; it only occurred to me as I was writing my post.  But I suspect you are court that it won't make a significant difference, as the calls are made from within the framework itself (which are already loaded).

Is there any way out of this mess? Is there anyway to use something like cflow()?  Is there no way to advise an already loaded class?

Thanks

Eric


On Aug 21, 2016 12:46 PM, "Alexander Kriegisch" <alexander@xxxxxxxxxxxxxx> wrote:

Hi Eric.

What is the problem with approach #1? That Struts classes are not loaded correctly anymore? Do you even want to advse them? If that is not necessary why not just exclude them by !within(org.apache.struts)?

Yes, class-loading sequence is relevant for AspectJ LTW.

Using call() instead of execution() does not solve the root cause of your problem, I assume. It only bloats the bytecode because many more joinpoints need to be woven.

Regards
--
Alexander Kriegisch
https://scrum-master.de
 
Eric B schrieb am 21.08.2016 15:03:
I have a "fragile" legacy app that is running on JBoss 4.  That is to say, that any changes to the app require a full manual regression test which are long and expensive.  I'm trying to add some specific logging to the app, so I figured that using AOP to intercept method executions would be the simplest way without altering the binaries.
 
But here is where I am running into classloading problems when I am trying to advise classes that are already loaded by the classloader by the time my ear gets loaded.
 
My EAR is structured as the follows:
 
EAR
 - webapp.war
    \ WEB-INF/lib
        - webstuff.jar
        - WebClasses.jar
        - struts.jar
 - EJB.jar
 - utils.jar
 
 
JBoss is set to load as parent-first, and modifying the sequence isn't an option.
 
So I have a few problems here:
1) If I drop my aspect.jar in my EAR/lib folder, and enable LTW on the command line, it is able to successfully advise all my classes in EJB.jar, utils.jar and webstuff.jar.  I am even able to advise methods in struts.jar, but unable to use any struts classes as the classloader for the aspect doesn't "see" anything in struts.jar (I get ClassDefNotFoundException).
 
2) If I move my aspect.jar into my WEB-INF/lib folder, it doesn't successfully advise anything in EJB.jar or utils.jar, I suspect b/c they are loaded prior to the aspect being loaded by the classloader.
 
My pointcuts are all "execution" pointcuts.
 
Similarly if I try to advise container classes with "execution" pointcuts, they never seem to trigger.
 
Is there a simple solution for this?  Does one need to take the class-loading sequence into account when using LTW?  Thinking outloud, would changing all my "execution" pointcuts to "call" make a difference?
 
My aop.xml is fairly basic:
   <aspectj>
            <aspects>
              <aspect name="com.security.logger.LoginLogger"/>
              <aspect name="com.security.logger.EJBAccessErrorLogger"/>
            </aspects>

            <weaver options="-verbose">
            </weaver>
   </aspectj>
Do I need to specify <includes> to the aspectj compiler?  I thought all classes were "included" by default.
 
Thanks!

Eric

_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users
_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users

_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users



Back to the top