yapkm01
yapkm01

Reputation: 3761

javaee : @Resource annotation not injecting JNDI resource

Here are my environment settings:
1. Apache Tomcat EE 1.6.2 (Java EE 6 certified)
2. Java 1.7.0_65
3. JAAS

A) WEB-INF/context.xml

<?xml version="1.0" encoding="UTF-8"?>
<context>
<!-- Use JAASRealm -->
<Realm className="org.apache.catalina.realm.JAASRealm" appName="JAASLoginModule"
    userClassNames="com.jaas.login.module.UserPrincipal" roleClassNames="com.jaas.login.module.RolePrincipal" />

<Resource name="ldapRes" 
          auth="Application"
          type="org.apache.directory.ldap.client.api.LdapNetworkConnection"
          factory="com.ldap.factory.services.LdapContextFactory"
          singleton="true" 
          java.naming.provider.url="ldap://127.0.0.1:389"
          java.naming.security.authentication="simple"
          java.naming.security.principal="cn=admin,dc=example,dc=com,dc=au"
          java.naming.security.credentials="a0120733@OPENLDAP" />
</context>

B) web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">

:

<resource-ref>
    <description>
        LDAP Resource
    </description>
    <res-ref-name>
        ldapResRef
    </res-ref-name>
    <lookup-name>
        java:comp/env/ldapRes
    </lookup-name>
  </resource-ref>

</web-app>

C) LdapContextFactory class

public class LdapContextFactory implements ObjectFactory {

public Object getObjectInstance(Object obj, Name name, Context nameCtx,
        Hashtable<?, ?> environment) throws Exception {

    System.out.println("getObjectInstance");
    Hashtable<Object, String> configurations = new Hashtable<Object, String>();
    Reference reference = (Reference) obj;
    Enumeration<RefAddr> references = reference.getAll();

    while (references.hasMoreElements()) {
        RefAddr address = references.nextElement();
        String type = address.getType();
        String content = (String) address.getContent();

        switch (type) {
        case Context.PROVIDER_URL:
            configurations.put(Context.PROVIDER_URL, content);
            break;
        case Context.SECURITY_AUTHENTICATION:
            configurations.put(Context.SECURITY_AUTHENTICATION, content);
            break;
        case Context.SECURITY_PRINCIPAL:
            configurations.put(Context.SECURITY_PRINCIPAL, content);
            break;
        case Context.SECURITY_CREDENTIALS:
            configurations.put(Context.SECURITY_CREDENTIALS, content);
            break;
        default:
            break;
        }
    }

    int startIndexIP = ((String) configurations.get(Context.PROVIDER_URL))
            .lastIndexOf("//") + 2;
    int lastIndexIP = ((String) configurations.get(Context.PROVIDER_URL))
            .lastIndexOf(':');
    String ldapHost = ((String) configurations.get(Context.PROVIDER_URL))
            .substring(startIndexIP, lastIndexIP);
    int ldapPort = Integer.parseInt(((String) configurations
            .get(Context.PROVIDER_URL)).substring(lastIndexIP + 1));

    return new LdapNetworkConnection(ldapHost, ldapPort);

}

}

D) JAASLoginModule class

public class JAASLoginModule implements LoginModule {
 :
public boolean login() throws LoginException {
    if (callbackHandler == null)
        throw new LoginException("no handler");

    NameCallback nameCall = new NameCallback("username: ");
    PasswordCallback passCall = new PasswordCallback("password: ", false);
    try {
        callbackHandler.handle(new Callback[]{nameCall, passCall});
    } catch (UnsupportedCallbackException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    System.out.println(nameCall.getName());
    System.out.println(passCall.getPassword());

    LdapConnection connection = new LdapResourceConnection().getLdapConnection();

    try {
        System.out.println(connection);
          :

 }

E) LdapResourceConnection class

public class LdapResourceConnection {

private LdapNetworkConnection ldapConnection;

public LdapConnection getLdapConnection() {
    System.out.println("GET ..");
    return ldapConnection;
}

@Resource(lookup="java:comp/env/ldapResRef")
public void setLdapConnection(LdapNetworkConnection ldapConnection) {
    System.out.println("SET ..");
    this.ldapConnection = ldapConnection;
}

}

Issue:
On the login module

LdapConnection connection = new LdapResourceConnection().getLdapConnection();

this fail to run the LdapResourceConnection setLdapConnection() method. What i get on this command is just the "GET .." gets printed but not the "SET ..".

Please help.
Thanks.

Upvotes: 0

Views: 748

Answers (1)

faissalb
faissalb

Reputation: 1749

Your problem is that you're creating LdapResourceConnection by your self so the container (application server/CDI) can't inject anything.

To be able to use injection into a bean this bean should be managed ( created / disposed ) by the container.

To correct this on your login module you should inject LdapResourceConnection

@Inject
LdapResourceConnection ldapResourceConnection;
...
LdapConnection connection = ldapResourceConnection.getLdapConnection()

Upvotes: 1

Related Questions