You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Arnaud Mergey <a_...@yahoo.fr.INVALID> on 2020/11/09 15:10:14 UTC

NPE while lookup resource in tomcat JNDI

Hello,
I have a tomcat app that is trying to list available JDBC Datasources it can find in tomcat JNDI Context
It fails with NPE when there is a ResourceLink in my app context.
It seems to be a bug in org.apache.naming.NamingContextBindingsEnumeration to me, but I may be wrong.
A minimal test to reproduce could be to define a global datasource in server.xml<Resource name="jdbc/MY_DS" auth="Container" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" type="javax.sql.DataSource" driverClassName="org.postgresql.Driver" url="jdbc:postgresql://localhost:5432/postgres" username="user" password="pass" maxActive="8" maxIdle="8" minIdle="0" maxWait="15000" initialSize="0" defaultAutoCommit="false" rollbackOnReturn="true" validationQuery="select 1" testOnBorrow="true" timeBetweenEvictionRunsMillis="45000" validationInterval="60000" />
in context.xml of a tomcat app 
<ResourceLink name="jdbc/MY_DS"          global="jdbc/MY_DS"          auth="container"          type="javax.sql.DataSource"/>

Executing this code        
        process((Context)new InitialContext().lookup("java:comp/env"), new ArrayList(), "java:comp/env")

with:
 private void process(Context context, List<String> list, String jNDIPrefix) throws NamingException { NamingEnumeration<Binding> objects = context .listBindings("");  while (objects.hasMore()) { try { Binding binding = objects.next(); Object obj = binding.getObject(); if (obj instanceof DataSource) { ist.add(jNDIPrefix + binding.getName()); } else if (obj instanceof Context) { process((Context) obj, list, jNDIPrefix + binding.getName()); } else if (obj instanceof Reference) { Object res = context.lookup(binding.getName());
 if (res instanceof DataSource) { list.add(jNDIPrefix + binding.getName()); } } } catch (NamingException e) { if (sLogger.isDebugEnabled()) { sLogger.debug("Exception while processing one JNDI element", e); } } } }
fails with
java.lang.NullPointerException at org.apache.naming.NamingContextBindingsEnumeration.nextElementInternal(NamingContextBindingsEnumeration.java:129) at org.apache.naming.NamingContextBindingsEnumeration.next(NamingContextBindingsEnumeration.java:71) at org.apache.naming.NamingContextBindingsEnumeration.next(NamingContextBindingsEnumeration.java:34)
After a quick debugin org.apache.naming.NamingContextBindingsEnumeration.nextElementInternal(), value for the ResourceLink is null (value = ctx.lookup(new CompositeName(entry.name));) but it should not, so the NPE in the return part Even if I am doing something illegal with my code (the recursive processing of the context, but would not see why), there should not be a NPE there anyway. Any thoughts ? 
Thanks,Arnaud

Re: NPE while lookup resource in tomcat JNDI

Posted by Arnaud Mergey <a_...@yahoo.fr.INVALID>.
 Hello Christopher,
Thanks for the reply, digging more into this, I found that the cause of my issue was a classloader issue.
Lookup for ResourceLink must be done in same classloader tomcat uses to register resources, otherwise org.apache.naming.factory.ResourceLinkFactory.getObjectInstance(Object, Name, Context, Hashtable<?, ?>) returns null 
(see org.apache.naming.factory.ResourceLinkFactory.validateGlobalResourceAccess(String))
Problem solved for me and it was in my code, but maybe having some logging there could help to understand this kind of issue.
Best,Arnaud
    Le lundi 9 novembre 2020 à 20:19:30 UTC+1, Christopher Schultz <ch...@christopherschultz.net> a écrit :  
 
 Arnaud,

Apologies for the top-post. Could you please:

1. Re-post preserving whitespace? Your code+config were unreadable when 
they made it to the mailing list.

2. Post the full (redacted if necessary) stack trace of the NPE.

3. Annotate your code with some line-numbers so we can match #1 and #2 
above.

Thanks,
-chris

On 11/9/20 10:10, Arnaud Mergey wrote:
> Hello,
> I have a tomcat app that is trying to list available JDBC Datasources it can find in tomcat JNDI Context
> It fails with NPE when there is a ResourceLink in my app context.
> It seems to be a bug in org.apache.naming.NamingContextBindingsEnumeration to me, but I may be wrong.
> A minimal test to reproduce could be to define a global datasource in server.xml<Resource name="jdbc/MY_DS" auth="Container" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" type="javax.sql.DataSource" driverClassName="org.postgresql.Driver" url="jdbc:postgresql://localhost:5432/postgres" username="user" password="pass" maxActive="8" maxIdle="8" minIdle="0" maxWait="15000" initialSize="0" defaultAutoCommit="false" rollbackOnReturn="true" validationQuery="select 1" testOnBorrow="true" timeBetweenEvictionRunsMillis="45000" validationInterval="60000" />
> in context.xml of a tomcat app
> <ResourceLink name="jdbc/MY_DS"          global="jdbc/MY_DS"          auth="container"          type="javax.sql.DataSource"/>
> 
> Executing this code
>          process((Context)new InitialContext().lookup("java:comp/env"), new ArrayList(), "java:comp/env")
> 
> with:
>  private void process(Context context, List<String> list, String jNDIPrefix) throws NamingException { NamingEnumeration<Binding> objects = context .listBindings("");  while (objects.hasMore()) { try { Binding binding = objects.next(); Object obj = binding.getObject(); if (obj instanceof DataSource) { ist.add(jNDIPrefix + binding.getName()); } else if (obj instanceof Context) { process((Context) obj, list, jNDIPrefix + binding.getName()); } else if (obj instanceof Reference) { Object res = context.lookup(binding.getName());
>  if (res instanceof DataSource) { list.add(jNDIPrefix + binding.getName()); } } } catch (NamingException e) { if (sLogger.isDebugEnabled()) { sLogger.debug("Exception while processing one JNDI element", e); } } } }
> fails with
> java.lang.NullPointerException at org.apache.naming.NamingContextBindingsEnumeration.nextElementInternal(NamingContextBindingsEnumeration.java:129) at org.apache.naming.NamingContextBindingsEnumeration.next(NamingContextBindingsEnumeration.java:71) at org.apache.naming.NamingContextBindingsEnumeration.next(NamingContextBindingsEnumeration.java:34)
> After a quick debugin org.apache.naming.NamingContextBindingsEnumeration.nextElementInternal(), value for the ResourceLink is null (value = ctx.lookup(new CompositeName(entry.name));) but it should not, so the NPE in the return part Even if I am doing something illegal with my code (the recursive processing of the context, but would not see why), there should not be a NPE there anyway. Any thoughts ?
> Thanks,Arnaud
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org

  

Re: NPE while lookup resource in tomcat JNDI

Posted by Christopher Schultz <ch...@christopherschultz.net>.
Arnaud,

Apologies for the top-post. Could you please:

1. Re-post preserving whitespace? Your code+config were unreadable when 
they made it to the mailing list.

2. Post the full (redacted if necessary) stack trace of the NPE.

3. Annotate your code with some line-numbers so we can match #1 and #2 
above.

Thanks,
-chris

On 11/9/20 10:10, Arnaud Mergey wrote:
> Hello,
> I have a tomcat app that is trying to list available JDBC Datasources it can find in tomcat JNDI Context
> It fails with NPE when there is a ResourceLink in my app context.
> It seems to be a bug in org.apache.naming.NamingContextBindingsEnumeration to me, but I may be wrong.
> A minimal test to reproduce could be to define a global datasource in server.xml<Resource name="jdbc/MY_DS" auth="Container" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" type="javax.sql.DataSource" driverClassName="org.postgresql.Driver" url="jdbc:postgresql://localhost:5432/postgres" username="user" password="pass" maxActive="8" maxIdle="8" minIdle="0" maxWait="15000" initialSize="0" defaultAutoCommit="false" rollbackOnReturn="true" validationQuery="select 1" testOnBorrow="true" timeBetweenEvictionRunsMillis="45000" validationInterval="60000" />
> in context.xml of a tomcat app
> <ResourceLink name="jdbc/MY_DS"          global="jdbc/MY_DS"          auth="container"          type="javax.sql.DataSource"/>
> 
> Executing this code
>          process((Context)new InitialContext().lookup("java:comp/env"), new ArrayList(), "java:comp/env")
> 
> with:
>   private void process(Context context, List<String> list, String jNDIPrefix) throws NamingException { NamingEnumeration<Binding> objects = context .listBindings("");  while (objects.hasMore()) { try { Binding binding = objects.next(); Object obj = binding.getObject(); if (obj instanceof DataSource) { ist.add(jNDIPrefix + binding.getName()); } else if (obj instanceof Context) { process((Context) obj, list, jNDIPrefix + binding.getName()); } else if (obj instanceof Reference) { Object res = context.lookup(binding.getName());
>   if (res instanceof DataSource) { list.add(jNDIPrefix + binding.getName()); } } } catch (NamingException e) { if (sLogger.isDebugEnabled()) { sLogger.debug("Exception while processing one JNDI element", e); } } } }
> fails with
> java.lang.NullPointerException at org.apache.naming.NamingContextBindingsEnumeration.nextElementInternal(NamingContextBindingsEnumeration.java:129) at org.apache.naming.NamingContextBindingsEnumeration.next(NamingContextBindingsEnumeration.java:71) at org.apache.naming.NamingContextBindingsEnumeration.next(NamingContextBindingsEnumeration.java:34)
> After a quick debugin org.apache.naming.NamingContextBindingsEnumeration.nextElementInternal(), value for the ResourceLink is null (value = ctx.lookup(new CompositeName(entry.name));) but it should not, so the NPE in the return part Even if I am doing something illegal with my code (the recursive processing of the context, but would not see why), there should not be a NPE there anyway. Any thoughts ?
> Thanks,Arnaud
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org