Proposal: javax.naming.spi.NamingManager.clearInitialContextFactoryBuilder()

Andrew Guibert aguibert at us.ibm.com
Sat May 6 23:55:01 UTC 2017



Hi all,

I've been cleaning up code that I work on to be Java 9 compatible, but have
ran into a blocker due to limitations of the Naming API.  I could work
around the blocker with an --add-opens, but I'd rather find a proper
solution.

*** Background
Currently the javax.naming.spi.NamingManager allows for setting a JVM-wide
InitialContextFactoryBuilder (ICFB) once and only once by using the static
NamingManager.setInitialContextFactoryBuilder() method [1].  The javadoc
clearly states:
> Once installed, the builder cannot be replaced.
If the set ICFB method is called after a ICFB is set, it will throw an
IllegalStateException.

This seems to be an overly-aggressive restriction of the API.  Currently my
product has code that reflects into the NamingManager class in order to
clear out the ICFB field using reflection.  To be Java 9 compliant, we
would like to remove this usage of deep reflection, but there are no clear
alternatives for doing so.

*** Use case
We have a JNDI server that may be started/stopped by other java code in the
same JVM.  If users stop the JNDI server we clear out the ICFB (using
reflection) when the JNDI server OSGi bundle deactivates, so that if a user
decides to start the JNDI server again in the same JVM, they may do so and
we simply set the ICFB when the JNDI server bundle activates.

*** Proposed Solution:
I could add a layer of indirection by creating an ICFB wrapper that
supports re-setting what ICFB it wraps.  However, this would cause the ICFB
wrapper and all other classes loaded using that bundle's classloader to be
leaked (since it can't be fully deactivated and garbage collected).  To
sort of work around this classloader leak, we would need to load the ICFB
wrapper using its own classloader.  Although the wrapper classloader would
still be leaked, it would have minimal impact because only the one wrapper
class would be leaked.

I am not sure why the "no resetting" restriction is on the NamingManager
API in the first place.  Is anyone aware why the API has this restriction?
In any case, the solution outlined above seems rather messy (as it only
solves the problem by mitigating a classloader leak), so I would like to
propose the following addition to the NamingManager API:

/**
 * Clears the InitialContextFactoryBuilder that was previously installed,
if any, so that a different one may be set at a later time.
 * @throws SecurityException - the builder cannot be cleared for security
reasons.
 * @see SecurityManager.checkSetFactory()
 */
public static void clearInitialContextFactoryBuilder()

[1]
http://download.java.net/java/jdk9/docs/api/javax/naming/spi/NamingManager.html#setInitialContextFactoryBuilder-javax.naming.spi.InitialContextFactoryBuilder-

- Andy


More information about the jdk9-dev mailing list