users@glassfish.java.net

Custom EJB Realm - JNDI fails: object is not an instance of declaring class

From: <glassfish_at_javadesktop.org>
Date: Wed, 17 Oct 2007 13:47:24 PDT

Hello,

I am implementing my custom realm class called EJBRealm that will delegate the login process to a Stateless Session Bean.

I first got the standard GlassFish JDBC realm to work as a custom realm in my own package. I got that to work very well.

Then I implemented the EJB’s and the EJBRealm (based on GF’s JDBCRealm), and configured the realm in glassfish (Actually sun java app server 9.1, 58b).

When I attempt to authenticate through BASIC, Several exceptions occur in the same program execution.

The first one is the most constant one:

com.sun.enterprise.security.LoginException: Unable to connect to datasource com.pstt.ejb.facade.jaas.LoginManagerFacadeRemote for database user {1}.
        at com.pstt.util.security.realm.EJBRealm.getRealmManager(EJBRealm.java:463)
        at com.pstt.util.security.realm.EJBRealm.isUserValid(EJBRealm.java:332)
        at com.pstt.util.security.realm.EJBRealm.authenticate(EJBRealm.java:310)
        at com.pstt.util.security.realm.EJBLoginModule.authenticate(EJBLoginModule.java:42)
        at com.sun.enterprise.security.auth.login.PasswordLoginModule.authenticateUser(PasswordLoginModule.java:90)
        at com.sun.appserv.security.AppservPasswordLoginModule.login(AppservPasswordLoginModule.java:184)
        at sun.reflect.GeneratedMethodAccessor70.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at javax.security.auth.login.LoginContext.invoke(LoginContext.java:769)
        at javax.security.auth.login.LoginContext.access$000(LoginContext.java:186)
        at javax.security.auth.login.LoginContext$4.run(LoginContext.java:683)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
        at javax.security.auth.login.LoginContext.login(LoginContext.java:579)
        at com.sun.enterprise.security.auth.LoginContextDriver.doPasswordLogin(LoginContextDriver.java:295)
        at com.sun.enterprise.security.auth.LoginContextDriver.login(LoginContextDriver.java:170)
        at com.sun.enterprise.security.auth.LoginContextDriver.login(LoginContextDriver.java:123)
        at com.sun.web.security.RealmAdapter.authenticate(RealmAdapter.java:479)
        at com.sun.web.security.RealmAdapter.authenticate(RealmAdapter.java:419)
        at org.apache.catalina.authenticator.BasicAuthenticator.authenticate(BasicAuthenticator.java:161)
        at com.sun.web.security.RealmAdapter.invokeAuthenticateDelegate(RealmAdapter.java:1146)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:627)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:609)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
        at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:206)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:150)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
        at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:270)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:637)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:568)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:813)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:339)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:261)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:212)
        at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265)
        at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)
Caused by: javax.naming.NamingException: ejb ref resolution error for remote business interfacecom.pstt.ejb.facade.jaas.LoginManagerFacadeRemote [Root exception is java.lang.IllegalArgumentException: object is not an instance of declaring class]
        at com.sun.ejb.EJBUtils.lookupRemote30BusinessObject(EJBUtils.java:367)
        at com.sun.ejb.containers.RemoteBusinessObjectFactory.getObjectInstance(RemoteBusinessObjectFactory.java:74)
        at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:304)
        at com.sun.enterprise.naming.SerialContext.lookup(SerialContext.java:344)
        at javax.naming.InitialContext.lookup(InitialContext.java:392)
        at com.pstt.util.security.realm.EJBRealm.getRealmManager(EJBRealm.java:459)
        ... 44 more
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
        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 com.sun.ejb.EJBUtils.lookupRemote30BusinessObject(EJBUtils.java:359)
        ... 49 more
        [LoginContext]: original security exception with detail msg replaced by new exception with empty detail msg
        [LoginContext]: original security exception: com.sun.enterprise.security.LoginException: Failed jdbc login for bob.
        [LoginContext]: login REQUIRED failure
        [LoginContext]: abort ignored
Howver, the second and third time I tried, the causes were different:

Caused by: javax.naming.NamingException: ejb ref resolution error for remote business interfacecom.pstt.ejb.facade.jaas.LoginManagerFacadeRemote [Root exception is java.lang.RuntimeException: Could not invoke defineClass!]
        at com.sun.ejb.EJBUtils.lookupRemote30BusinessObject(EJBUtils.java:367)
        at com.sun.ejb.containers.RemoteBusinessObjectFactory.getObjectInstance(RemoteBusinessObjectFactory.java:74)
        at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:304)
        at com.sun.enterprise.naming.SerialContext.lookup(SerialContext.java:344)
        at javax.naming.InitialContext.lookup(InitialContext.java:392)
        at com.pstt.util.security.realm.EJBRealm.getRealmManager(EJBRealm.java:459)
        ... 44 more
Caused by: java.lang.RuntimeException: Could not invoke defineClass!
        at com.sun.corba.ee.impl.codegen.CodeGeneratorUtil.makeClass(CodeGeneratorUtil.java:98)
        at com.sun.corba.ee.spi.codegen.Wrapper._generate(Wrapper.java:1051)
        at com.sun.ejb.EJBUtils.generateAndLoad(EJBUtils.java:531)
        at com.sun.ejb.EJBUtils.loadGeneratedGenericEJBHomeClass(EJBUtils.java:462)
        at com.sun.ejb.EJBUtils.lookupRemote30BusinessObject(EJBUtils.java:340)
        ... 49 more
Caused by: java.lang.reflect.InvocationTargetException
        at sun.reflect.GeneratedMethodAccessor79.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at com.sun.corba.ee.impl.codegen.CodeGeneratorUtil.makeClass(CodeGeneratorUtil.java:95)
        ... 53 more
Caused by: java.lang.LinkageError: loader (instance of com/sun/appserv/server/util/ASURLClassLoader): attempted duplicate class definition for name: "com/sun/ejb/codegen/GenericEJBHome_Generated"
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
        ... 57 more
        [LoginContext]: original security exception with detail msg replaced by new exception with empty detail msg
        [LoginContext]: original security exception: com.sun.enterprise.security.LoginException: Failed jdbc login for bob.
        [LoginContext]: login REQUIRED failure
        [LoginContext]: abort ignored

Caused by: javax.naming.NamingException: ejb ref resolution error for remote business interfacecom.pstt.ejb.facade.jaas.LoginManagerFacadeRemote [Root exception is java.lang.ClassNotFoundException: com.pstt.ejb.facade.jaas._LoginManagerFacadeRemote_Wrapper]
        at com.sun.ejb.EJBUtils.lookupRemote30BusinessObject(EJBUtils.java:367)
        at com.sun.ejb.containers.RemoteBusinessObjectFactory.getObjectInstance(RemoteBusinessObjectFactory.java:74)
        at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:304)
        at com.sun.enterprise.naming.SerialContext.lookup(SerialContext.java:344)
        at javax.naming.InitialContext.lookup(InitialContext.java:392)
        at com.pstt.util.security.realm.EJBRealm.getRealmManager(EJBRealm.java:459)
        ... 44 more
Caused by: java.lang.ClassNotFoundException: com.pstt.ejb.facade.jaas._LoginManagerFacadeRemote_Wrapper
        at com.sun.appserv.server.util.ASURLClassLoader.loadClass(ASURLClassLoader.java:129)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
        at com.sun.ejb.EJBUtils.createRemoteBusinessObject(EJBUtils.java:579)
        at com.sun.ejb.EJBUtils.lookupRemote30BusinessObject(EJBUtils.java:363)
        ... 49 more
        [LoginContext]: original security exception with detail msg replaced by new exception with empty detail msg
        [LoginContext]: original security exception: com.sun.enterprise.security.LoginException: Failed jdbc login for bob.
        [LoginContext]: login REQUIRED failure
        [LoginContext]: abort ignored
The get realm manager gets the SLSB like so:

    private LoginManagerFacadeRemote getRealmManager() throws LoginException {
        final String ejbJndi = this.getProperty(PARAM_EJB_JNDI); //name is correctly bound
        try{
            InitialContext ic = new InitialContext();
            LoginManagerFacadeRemote facade = (LoginManagerFacadeRemote) ic.lookup(ejbJndi); //line 463
            return facade;
        } catch(Exception ex) {


The bean’s methods are called like this:

    private boolean isUserValid(String user, String password) {
        boolean valid = false;
        LoginManagerFacadeRemote loginManager;
        try {
            String hpwd = hashPassword(password);
            loginManager = getRealmManager();
            return loginManager.isUserValid(user, password);
 …

Or like this:

    private String[] findGroups(String user) {
        LoginManagerFacadeRemote loginManager;
        try {
            loginManager = getRealmManager();
            return loginManager.findGroups(user);
...

As you can tell, I am not doing anything complex. I have tried a little with the @ejb annotation, mostly with JNDI lookups, and managed to come back to the same error in both approaches.

I first had a bunch of class loading issues, got past all of those (I think) but I am not yet capable of authenticating. Digging into the source code, i discovered that the error generates in a call in

com.sun.ejb.EJBUtils(EJBUtils.java:359)
Which executes:

            final java.rmi.Remote delegate = (java.rmi.Remote)
                createMethod.invoke(genericHomeObj,
                                    generatedRemoteIntfName);

createMethod reports in the debugger as:
public abstract java.rmi.Remote com.sun.ejb.codegen.GenericEJBHome_Generated.create(java.lang.String) throws java.rmi.RemoteException

generic home object in the debugger reports as
"com.sun.ejb.codegen._GenericEJBHome_Generated_DynamicStub"

So it seems that the generic home object is not a subclass or implementation of a valid home object, because it reports: “object is not an instance of declaring class” so it is not being recognized when the “create” message is sent to it.

Maybe for some reason "com.sun.ejb.codegen._GenericEJBHome_Generated_DynamicStub" is not recognized as a “com.sun.ejb.codegen.GenericEJBHome_Generated” ????

Any thoughts or ideas???

I will try to build a minimal EAR to reproduce the problem.

Thanks for reading this far!!!!

Federico Vela
[Message sent by forum member 'fedevela' (fedevela)]

http://forums.java.net/jive/thread.jspa?messageID=240758