PDA

View Full Version : UnknownAdviceTypeException: No adapter for Advice of class



aaron8tang
Dec 1st, 2004, 11:32 PM
Hi, Ben

If I wanna call my protected business method in jsp code, do I have to use AspectJ (JoinPoint) Security Interceptor?

I've used AOP Alliance (MethodInvocation) Security Interceptor, it doesn't intercept my call, so I try an AspectJ interceptor according to your instruction in the reference document.

1.configure AspectJSecurityInterceptor in the Spring application context:



<bean id="positionManagerSecurity" class="net.sf.acegisecurity.intercept.method.aspectj.Aspe ctJSecurityInterceptor">
<property name="validateConfigAttributes"><value>true</value></property>
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
<property name="accessDecisionManager"><ref local="positionAccessDecisionManager"/></property>
<property name="afterInvocationManager"><ref local="afterInvocationManager"/></property>
<property name="objectDefinitionSource">
<value>
com.xxx.jaidwapfactory.security.SecurityPositionMa nager.addPosition=ROLE_USER
com.xxx.jaidwapfactory.security.SecurityPositionMa nager.removePosition=ACL_CONTACT_ADMIN
com.xxx.jaidwapfactory.security.SecurityPositionMa nager.getPositions=AFTER_ACL_COLLECTION_READ
com.xxx.jaidwapfactory.security.SecurityPositionMa nager.getPosition=AFTER_ACL_READ
</value>
</property>
</bean>


2.define an AspectJ aspect:
I just change the pointcut expression from yours:)



package com.xxx.jaidwapfactory.security;

/**
* @author cookman
*
*/
import net.sf.acegisecurity.intercept.method.aspectj.Aspe ctJSecurityInterceptor;
import net.sf.acegisecurity.intercept.method.aspectj.Aspe ctJCallback;
import org.springframework.beans.factory.InitializingBean ;

public aspect DomainObjectInstanceSecurityAspect implements InitializingBean &#123;

private AspectJSecurityInterceptor securityInterceptor;

pointcut domainObjectInstanceExecution&#40;&#41;&#58;
execution&#40;public * com.xxx.jaidwapfactory.security.SecurityPositionMa nager+.*&#40;..&#41;&#41; && !within&#40;DomainObjectInstanceSecurityAspect&#41;;

Object around&#40;&#41;&#58; domainObjectInstanceExecution&#40;&#41; &#123;
if &#40;this.securityInterceptor != null&#41; &#123;
AspectJCallback callback = new AspectJCallback&#40;&#41; &#123;
public Object proceedWithObject&#40;&#41; &#123;
return proceed&#40;&#41;;
&#125;
&#125;;
return this.securityInterceptor.invoke&#40;thisJoinPoint, callback&#41;;
&#125; else &#123;
return proceed&#40;&#41;;
&#125;
&#125;

public AspectJSecurityInterceptor getSecurityInterceptor&#40;&#41; &#123;
return securityInterceptor;
&#125;

public void setSecurityInterceptor&#40;
AspectJSecurityInterceptor securityInterceptor&#41; &#123;
this.securityInterceptor = securityInterceptor;
&#125;

public void afterPropertiesSet&#40;&#41; throws Exception &#123;
if &#40;this.securityInterceptor == null&#41;
throw new IllegalArgumentException&#40;"securityInterceptor required"&#41;;
&#125;
&#125;


3.configure Spring to load the aspect:



<bean id="domainObjectInstanceSecurityAspect"
class="com.xxx.jaidwapfactory.security.DomainObjectInstan ceSecurityAspect"
factory-method="aspectOf">
<property name="securityInterceptor"><ref bean="positionManagerSecurity"/></property>
</bean>


4.compile source code with aspectj iajc ant task and deploy all

but I get the following error msg:



11&#58;18&#58;34,248 ERROR ContextLoader,Thread-1&#58;114 - Context initialization failed
org.springframework.beans.factory.BeanCreationExce ption&#58; Error creating bean with name 'positionManager' defined in ServletContext resource &#91;/WEB-INF/applicationContext-common-business.xml&#93;&#58; Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigExcepti on&#58; Unknown advisor type class net.sf.acegisecurity.intercept.method.aspectj.Aspe ctJSecurityInterceptor; Can only include Advisor or Advice type beans in interceptorNames chain except for last entry,which may also be target or TargetSource; nested exception is org.springframework.aop.framework.adapter.UnknownA dviceTypeException&#58; No adapter for Advice of class &#91;net.sf.acegisecurity.intercept.method.aspectj.Asp ectJSecurityInterceptor&#93;
org.springframework.aop.framework.AopConfigExcepti on&#58; Unknown advisor type class net.sf.acegisecurity.intercept.method.aspectj.Aspe ctJSecurityInterceptor; Can only include Advisor or Advice type beans in interceptorNames chain except for last entry,which may also be target or TargetSource; nested exception is org.springframework.aop.framework.adapter.UnknownA dviceTypeException&#58; No adapter for Advice of class &#91;net.sf.acegisecurity.intercept.method.aspectj.Asp ectJSecurityInterceptor&#93;
org.springframework.aop.framework.adapter.UnknownA dviceTypeException&#58; No adapter for Advice of class &#91;net.sf.acegisecurity.intercept.method.aspectj.Asp ectJSecurityInterceptor&#93;
at org.springframework.aop.framework.adapter.DefaultA dvisorAdapterRegistry.wrap&#40;DefaultAdvisorAdapterRe gistry.java&#58;49&#41;
at org.springframework.aop.framework.ProxyFactoryBean .namedBeanToAdvisor&#40;ProxyFactoryBean.java&#58;454&#41;
at org.springframework.aop.framework.ProxyFactoryBean .addAdvisorOnChainCreation&#40;ProxyFactoryBean.java&#58;4 17&#41;
at org.springframework.aop.framework.ProxyFactoryBean .createAdvisorChain&#40;ProxyFactoryBean.java&#58;321&#41;
at org.springframework.aop.framework.ProxyFactoryBean .setBeanFactory&#40;ProxyFactoryBean.java&#58;193&#41;
at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.createBean&#40;AbstractAuto wireCapableBeanFactory.java&#58;271&#41;
at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.createBean&#40;AbstractAuto wireCapableBeanFactory.java&#58;193&#41;
at org.springframework.beans.factory.support.Abstract BeanFactory.getBean&#40;AbstractBeanFactory.java&#58;240&#41;
at org.springframework.beans.factory.support.Abstract BeanFactory.getBean&#40;AbstractBeanFactory.java&#58;163&#41;
at org.springframework.beans.factory.support.DefaultL istableBeanFactory.preInstantiateSingletons&#40;Defaul tListableBeanFactory.java&#58;230&#41;
at org.springframework.context.support.AbstractApplic ationContext.refresh&#40;AbstractApplicationContext.ja va&#58;304&#41;
at org.springframework.web.context.support.XmlWebAppl icationContext.refresh&#40;XmlWebApplicationContext.ja va&#58;131&#41;
at org.springframework.web.context.ContextLoader.crea teWebApplicationContext&#40;ContextLoader.java&#58;167&#41;
at org.springframework.web.context.ContextLoader.init WebApplicationContext&#40;ContextLoader.java&#58;101&#41;
at org.springframework.web.context.ContextLoaderListe ner.contextInitialized&#40;ContextLoaderListener.java&#58; 48&#41;
at org.apache.catalina.core.StandardContext.listenerS tart&#40;StandardContext.java&#58;3631&#41;
at org.apache.catalina.core.StandardContext.start&#40;Sta ndardContext.java&#58;4065&#41;
at org.apache.catalina.core.ContainerBase.addChildInt ernal&#40;ContainerBase.java&#58;755&#41;
at org.apache.catalina.core.ContainerBase.addChild&#40;Co ntainerBase.java&#58;739&#41;
at org.apache.catalina.core.StandardHost.addChild&#40;Sta ndardHost.java&#58;525&#41;
at org.apache.catalina.startup.HostConfig.deployDirec tory&#40;HostConfig.java&#58;886&#41;
at org.apache.catalina.startup.HostConfig.deployDirec tories&#40;HostConfig.java&#58;849&#41;
at org.apache.catalina.startup.HostConfig.deployApps&#40; HostConfig.java&#58;474&#41;
at org.apache.catalina.startup.HostConfig.start&#40;HostC onfig.java&#58;1079&#41;
at org.apache.catalina.startup.HostConfig.lifecycleEv ent&#40;HostConfig.java&#58;310&#41;
at org.apache.catalina.util.LifecycleSupport.fireLife cycleEvent&#40;LifecycleSupport.java&#58;119&#41;
at org.apache.catalina.core.ContainerBase.start&#40;Conta inerBase.java&#58;1011&#41;
at org.apache.catalina.core.StandardHost.start&#40;Standa rdHost.java&#58;718&#41;
at org.apache.catalina.core.ContainerBase.start&#40;Conta inerBase.java&#58;1003&#41;
at org.apache.catalina.core.StandardEngine.start&#40;Stan dardEngine.java&#58;437&#41;
at org.apache.catalina.core.StandardService.start&#40;Sta ndardService.java&#58;450&#41;
at org.apache.catalina.core.StandardServer.start&#40;Stan dardServer.java&#58;2010&#41;
at org.apache.catalina.startup.Catalina.start&#40;Catalin a.java&#58;537&#41;
at sun.reflect.NativeMethodAccessorImpl.invoke0&#40;Nativ e Method&#41;
at sun.reflect.NativeMethodAccessorImpl.invoke&#40;Native MethodAccessorImpl.java&#58;39&#41;
at sun.reflect.DelegatingMethodAccessorImpl.invoke&#40;De legatingMethodAccessorImpl.java&#58;25&#41;
at java.lang.reflect.Method.invoke&#40;Method.java&#58;585&#41;
at org.apache.catalina.startup.Bootstrap.start&#40;Bootst rap.java&#58;271&#41;
at org.apache.catalina.startup.Bootstrap.main&#40;Bootstr ap.java&#58;409&#41;

Ben Alex
Dec 2nd, 2004, 02:35 PM
You only need AspectJ if your SecurityPositionManager is NOT coming from the Spring IoC container. If your SecurityPositonManager is coming from the Spring IoC container, you're far better off using MethodSecurityInterceptor with one of Spring's standard proxy factories.

I'll take a punt and assume SecurityPositionManager is coming from Spring IoC, in which case have you tried usiing MethodSecurityInterceptor with debug-level logging? If so, what is the output? Also, could you post your application context XML so I can see how you've configured it.

aaron8tang
Dec 3rd, 2004, 03:00 AM
Hi, Ben

I new a long post :roll:

http://forum.springframework.org/showthread.php?t=11804

I've tried using MethodSecurityInterceptor with debug-level logging and add some debug logging code. In your contacts example, it's ok. But in my own case ,nothing outputted :cry: .

output example of contacts application:



16:40:59,162 DEBUG MethodSecurityInterceptor:? - MethodInvocation=Invocation: method 'create', arguments [sample.contact.Contact@1f2f70a: Id: null; Name: dispatch2; Email: aarontang]; target is of class [sample.contact.ContactManagerBackend]method=create
....

aaron8tang
Dec 3rd, 2004, 03:18 AM
By the way, Ben, I fix two little bug, (wish i do the right thing :) )

1.JdbcDaoImpl.java



public static final String DEF_OBJECT_PROPERTIES_QUERY = "SELECT CHILD.ID, CHILD.OBJECT_IDENTITY, CHILD.ACL_CLASS, PARENT.OBJECT_IDENTITY as PARENT_OBJECT_IDENTITY FROM acl_object_identity as CHILD LEFT OUTER JOIN acl_object_identity as PARENT ON CHILD.parent_object=PARENT.id WHERE CHILD.object_identity = ?";//PARENT.id=CHILD.parent_object and


otherwise the id column is ambiguous. And when there is no object hierarchy, "where condition" PARENT.id=CHILD.parent_object always return null

2.HttpSessionIntegrationFilter



if&#40;&#40;&#40;HttpServletRequest&#41; request&#41;.isRequestedSessionIdValid&#40;&#41;&#41; &#123;

HttpSession httpSession = &#40;&#40;HttpServletRequest&#41; request&#41;.getSession&#40;&#41;;

if &#40;httpSession != null&#41; &#123;
httpSession.setAttribute&#40;ACEGI_SECURITY_AUTHENTICA TION_KEY,
authentication&#41;;
updateOtherLocations&#40;httpSession, authentication&#41;;
&#125;
&#125;


otherwise when logging off(I use tomcat 5.5.4), there is error msg like "cannot commit to container....response is close"

Ben Alex
Dec 4th, 2004, 11:30 PM
Thanks Aaron, I've added both fixes to CVS.

aaron8tang
Dec 5th, 2004, 06:50 AM
Ben,

Have you written or goning to write an AspectJ interceptor example/testcase?

I tried to do it according to your example described in the reference document, but failed to work:(.

The first post under this topic is my experience, could you give me some advice?

I try to use an AspectJ interceptor because that I know JBoss AOP cannot intercept method call in jsp code, but AspectJ can do it with its compile time weaving. I'm not sure Spring AOP will do the same job as AspectJ, so I want to have a test.

aaron8tang
Dec 5th, 2004, 08:47 AM
Ben,

Is AspectJSecurityInterceptor still in progress?

In my test case, the error is obvious, because in spring reference, interceptorNames is restricted to be "String array of Advisor, interceptor or other advice names to apply", but AspectJSecurityInterceptor belongs to none of these, so UnknownAdviceTypeException is thrown.

Ben Alex
Dec 5th, 2004, 03:18 PM
Aaron, I've gone through your configuration very closely and can't see the problem. Would you please post your full applicationContext-common-business.xml so I can take a look?

There is no sample included with Acegi Security for AspectJ. It does work, as I had it going when I wrote the interceptor, but I didn't bother with a sample app due to the more complicated compliation processes and dependencies. We're just wrapping up a major Maven migration and I didn't want to extend it with an AspectJ sample. Personally I found the CURRENT AspectJ IDE integration impractical for real applications due to the unreliable incremental compilation. Everytime I changed an XML file or whatever an entire rebuild took place, which is just not usable if you've got 200 classes. Generally with a little thought and package protected methods you can direct security-sensitive calls through a services layer object - which can happily exist in Spring's IoC container and work with an AOP Alliance MethodInterceptor such as MethodSecurityInterceptor - and avoid AspectJ for security.

Still, we'll try and get your application working, if you could just post the XML file.

aaron8tang
Dec 5th, 2004, 07:18 PM
Ben, what I've posted in http://forum.springframework.org/showthread.php?t=11804 is my full configuration. Sorry for the inconvenience. At that time, I thought they belong to different topic.

Even after I change the applicationContext-common-authorization.xml according to your suggestion, it doesn't work. :cry:

Ben Alex
Dec 6th, 2004, 04:05 PM
The configuration shown in that thread shows no AspectJ-related beans, and it shows MethodSecurityInterceptor together with a ProxyFactoryBean. If using AspectJ the aspect should be shown, and there is no need for a ProxyFactoryBean. Could you confirm it was removed?