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