Announcement Announcement Module
Collapse
No announcement yet.
ClassCast Exception when Using RemoteAuthenticationManager Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • ClassCast Exception when Using RemoteAuthenticationManager

    Hi together,
    we just implemented a client-server-application, by using spring-security 2.0.3, spring-rcp-snapshot (patched to work with spring-security) and hessian 3.1.3.

    As the spring example does not work, we implemented our own (de-)serializer for hessian (see the following code).

    Code:
    public class GrantedAuthoritySerializerFactory extends SerializerFactory{
    	private GrantedAuthorityDeserializer grantedAuthorityDeserializer = new GrantedAuthorityDeserializer();
    	private GrantedAuthoritySerializer grantedAuthoritysSerializer = new GrantedAuthoritySerializer();
    	
    	
    	@Override
    	public Deserializer getDeserializer(Class clazz) throws HessianProtocolException {
    		if (GrantedAuthority.class.isAssignableFrom(clazz)){
    			return grantedAuthorityDeserializer;
    		}
    		return super.getDeserializer(clazz);
    	}
    
    	@Override
    	public Serializer getSerializer(Class clazz) throws HessianProtocolException {
    		if (GrantedAuthority.class.isAssignableFrom(clazz)){
    			return grantedAuthoritysSerializer;
    		}
    		return super.getSerializer(clazz);
    	}
    Code:
    public class GrantedAuthorityDeserializer  extends AbstractDeserializer {
    	
    	@Override
    	public Object readObject(AbstractHessianInput in) throws IOException {
    		return super.readObject(in);
    	}
    
    	public GrantedAuthority readMap(AbstractHessianInput in) throws IOException {
    
    		String clazz = null;
    		String value = null;
    		
    		while (!in.isEnd()) {
    			clazz = in.readString();
    			value = in.readString();
    		}
    		in.readMapEnd();
    
    		if (clazz == null)
    			throw new IOException(
    					"Expected GrantedAuthorityImpl class name");
    		if (value == null)
    			throw new IOException(
    					"Expected GrantedAuthorityImpl class value");
    
    		GrantedAuthority authority = new GrantedAuthorityImpl(value);
    		return authority;
    	}
    Code:
    public class GrantedAuthoritySerializer extends AbstractSerializer{ 
    
    	@Override
    	public void writeObject(Object obj, AbstractHessianOutput out) throws IOException {
    		if (!(obj instanceof GrantedAuthorityImpl)) throw new IOException("GrantedAuthoritySerializer can only serialize GrantedAuthorityImpl objects");
    		GrantedAuthority authority = (GrantedAuthorityImpl) obj;
    		Class cl = obj.getClass();
    		out.writeMapBegin(cl.getName());
            out.writeString(cl.getName());
            out.writeString(authority.getAuthority());
            out.writeMapEnd();
    	}
    
    }
    We registered the service in the server like this:
    Code:
     <!-- Hessian exporter for the RemoteAuthenticationManager -->
      <bean name="/RemoteAuthenticationManager" class="org.springframework.remoting.caucho.HessianServiceExporter">
        <property name="service" ref="remoteAuthenticationManager"/>
        <property name="serviceInterface" value="org.springframework.security.providers.rcp.RemoteAuthenticationManager" />
        <property name="serializerFactory" ref="serializerFactory"/>
        <property name="debug" value="true"/>
      </bean>
      
      <bean id="serializerFactory" class="de.hr.ec.fsm.common.GrantedAuthoritySerializerFactory"/>
    and in the client:
    Code:
    <!-- Proxy for the Hessian-exported RemoteAuthenticationManager -->
    	<bean id="remoteAuthenticationManager" class="org.springframework.remoting.caucho.HessianProxyFactoryBean">
    		<property name="serviceInterface" value="org.springframework.security.providers.rcp.RemoteAuthenticationManager" />
    		<property name="serviceUrl" value="http://${serverName}:${httpPort}${contextPath}/ws/RemoteAuthenticationManager" />
    		<property name="serializerFactory" ref="serializerFactory"/>
    		<property name="debug" value="true"/>
    	</bean>
    	 
    	 <bean id="serializerFactory" class="de.hr.ec.fsm.common.GrantedAuthoritySerializerFactory"/>
    Our problem is an internal ClassCastException (see the stacktrace):
    Code:
    java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Lorg.springframework.security.GrantedAuthority;
    	at $Proxy22.attemptAuthentication(Unknown Source)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at org.springframework.remoting.caucho.HessianClientInterceptor.invoke(HessianClientInterceptor.java:218)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    	at $Proxy23.attemptAuthentication(Unknown Source)
    	at org.springframework.security.providers.rcp.RemoteAuthenticationProvider.authenticate(RemoteAuthenticationProvider.java:61)
    	at org.springframework.security.providers.ProviderManager.doAuthentication(ProviderManager.java:195)
    	at org.springframework.security.AbstractAuthenticationManager.authenticate(AbstractAuthenticationManager.java:46)
    	at org.springframework.richclient.security.support.DefaultApplicationSecurityManager.doLogin(DefaultApplicationSecurityManager.java:160)
    	at de.hr.ec.fsm.gui.commands.LoginCommand$1.onFinish(LoginCommand.java:122)
    	at org.springframework.richclient.dialog.ApplicationDialog$1.doExecuteCommand(ApplicationDialog.java:502)
    	at org.springframework.richclient.command.ActionCommand.execute(ActionCommand.java:195)
    	at org.springframework.richclient.command.ActionCommand$1.actionPerformed(ActionCommand.java:126)
    	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2028)
    	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2351)
    	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
    	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
    	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
    	at java.awt.Component.processMouseEvent(Component.java:6126)
    	at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
    	at java.awt.Component.processEvent(Component.java:5891)
    	at java.awt.Container.processEvent(Container.java:2102)
    	at java.awt.Component.dispatchEventImpl(Component.java:4497)
    	at java.awt.Container.dispatchEventImpl(Container.java:2160)
    	at java.awt.Component.dispatchEvent(Component.java:4327)
    	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4366)
    	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4030)
    	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3960)
    	at java.awt.Container.dispatchEventImpl(Container.java:2146)
    	at java.awt.Window.dispatchEventImpl(Window.java:2440)
    	at java.awt.Component.dispatchEvent(Component.java:4327)
    	at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
    	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:300)
    	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:210)
    	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:204)
    	at java.awt.Dialog$1.run(Dialog.java:1045)
    	at java.awt.Dialog$3.run(Dialog.java:1097)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.awt.Dialog.show(Dialog.java:1095)
    	at java.awt.Component.show(Component.java:1422)
    	at java.awt.Component.setVisible(Component.java:1375)
    	at java.awt.Window.setVisible(Window.java:806)
    	at java.awt.Dialog.setVisible(Dialog.java:985)
    	at org.springframework.richclient.dialog.ApplicationDialog.showDialog(ApplicationDialog.java:421)
    	at de.hr.ec.fsm.gui.commands.LoginCommand.doExecuteCommand(LoginCommand.java:157)
    	at org.springframework.richclient.command.ActionCommand.execute(ActionCommand.java:195)
    	at de.hr.ec.fsm.gui.FSMLifecycleAdvisor.onCommandsCreated(FSMLifecycleAdvisor.java:42)
    	at org.springframework.richclient.application.support.AbstractApplicationWindow.<init>(AbstractApplicationWindow.java:85)
    	at com.jidesoft.spring.richclient.docking.JideApplicationWindow.<init>(JideApplicationWindow.java:56)
    	at com.jidesoft.spring.richclient.docking.JideApplicationWindow.<init>(JideApplicationWindow.java:51)
    	at com.jidesoft.spring.richclient.docking.JideApplicationWindowFactory$1.<init>(JideApplicationWindowFactory.java:76)
    	at com.jidesoft.spring.richclient.docking.JideApplicationWindowFactory.createApplicationWindow(JideApplicationWindowFactory.java:76)
    	at org.springframework.richclient.application.Application.createNewWindow(Application.java:182)
    	at org.springframework.richclient.application.Application.openWindow(Application.java:163)
    	at org.springframework.richclient.application.Application.start(Application.java:244)
    	at org.springframework.richclient.application.ApplicationLauncher$1.run(ApplicationLauncher.java:307)
    	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:199)
    	at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
    	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:300)
    	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:210)
    	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:200)
    	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:195)
    	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:187)
    	at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
    Does anyone has an idea, whats going wrong here?

  • #2
    I'm using acegi 1.0.2 and hessian 3.1.3 with spring 2.0. I'm using Java 5

    When accessing remotely my service using hessian I also get a ClassCastException:

    Caused by: java.lang.ClassCastException: java.util.HashSet

    After some remote debuggin it seems Hessian has difficulties with parameterized generic classes, be careful.

    What's interesting is that it does not occurs if I expose and invoke the service using EJB or SpringHTTP invokers...

    Fred

    Comment

    Working...
    X