9 Replies Latest reply on Feb 4, 2009 6:03 PM by Andrew Rubinger

    JBoss 5.0.0.GA: jboss.entity.manager.factory.jndi.name w/ su

    Matt C Newbie

      I'm upgrading an enterprise app from JBoss 4.2.1.GA to JBoss 5.0.0.GA and have hit a snag.

      In persistence.xml, the property jboss.entity.manager.factory.jndi.name should allow binding EntityManagerFactory instances into JNDI. From what I've read, this does work in the GA release.
      I bind EMFs into a subcontext though, i.e. a directory in JNDI, in order to enumerate them programatically. i.e.:

      +- PU1: InjectedEntityManagerFactory
      +- PU2: InjectedEntityManagerFactory ...

      This used to work, but doesn't seem to work in 5.0.0.GA.


      2009-01-13 17:30:35,482 ERROR [org.jboss.kernel.plugins.dependency.AbstractKernelController] (main) Error installing to Start: name=persistence.unit:unitName=Application.ear/MyApp.jar#PU1$
      javax.naming.NameNotFoundException: persistence-units not bound
       at org.jnp.server.NamingServer.getBinding(NamingServer.java:771)
       at org.jnp.server.NamingServer.getBinding(NamingServer.java:779)
       at org.jnp.server.NamingServer.getObject(NamingServer.java:785)
       at org.jnp.server.NamingServer.rebind(NamingServer.java:244)
       at org.jnp.interfaces.NamingContext.rebind(NamingContext.java:562)
       at org.jnp.interfaces.NamingContext.rebind(NamingContext.java:527)
       at javax.naming.InitialContext.rebind(InitialContext.java:408)
       at org.jboss.util.naming.NonSerializableFactory.rebind(NonSerializableFactory.java:185)
       at org.jboss.jpa.deployment.PersistenceUnitDeployment.start(PersistenceUnitDeployment.java:325)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

      Here I think is the relevant code in PersistenceUnitDeployment.java:
       String entityManagerFactoryJndiName = (String) props.get("jboss.entity.manager.factory.jndi.name");
       if (entityManagerFactoryJndiName != null)
       EntityManagerFactory injectedFactory = new InjectedEntityManagerFactory(managedFactory);
       NonSerializableFactory.rebind(initialContext, entityManagerFactoryJndiName, injectedFactory);

      NonSerializableFactory.rebind() looks like this:
       /** A convience method that simplifies the process of rebinding a
       non-serializable object into a JNDI context.
       @param ctx, the JNDI context to rebind to.
       @param key, the key to use in both the NonSerializableFactory map and JNDI. It
       must be a valid name for use in ctx.bind().
       @param target, the non-Serializable object to bind.
       @throws NamingException, thrown on failure to rebind key into ctx.
       public static synchronized void rebind(Context ctx, String key, Object target) throws NamingException
       NonSerializableFactory.rebind(key, target);
       // Bind a reference to target using NonSerializableFactory as the ObjectFactory
       String className = target.getClass().getName();
       String factory = NonSerializableFactory.class.getName();
       StringRefAddr addr = new StringRefAddr("nns", key);
       Reference memoryRef = new Reference(className, addr, factory, null);
       ctx.rebind(key, memoryRef);

      The NonSerializableFactory.rebind() method signature used by PersistenceUnitDeployment won't create subcontexts as needed.

      There is another method available which looks like it would solve my problem if used instead with a createSubcontexts argument of true:

       /** A convience method that simplifies the process of rebinding a
       non-zerializable object into a JNDI context. This version binds the
       target object into the default IntitialContext using name path.
       @param name, the name to use as JNDI path name. The key into the
       NonSerializableFactory map is obtained from the toString() value of name.
       The name parameter cannot be a 0 length name.
       @param target, the non-Serializable object to bind.
       @param createSubcontexts, a flag indicating if subcontexts of name should
       be created if they do not already exist.
       @throws NamingException, thrown on failure to rebind key into ctx.
       public static synchronized void rebind(Name name, Object target,
       boolean createSubcontexts) throws NamingException
       String key = name.toString();
       InitialContext ctx = new InitialContext();
       if( createSubcontexts == true && name.size() > 1 )
       int size = name.size() - 1;
       Util.createSubcontext(ctx, name.getPrefix(size));
       rebind(ctx, key, target);

      This post is related to another forum post but seems to be a distinct use case. Here's the related post:

      If I have identified the issue correctly; Is JBoss intended to still support the creation of subcontexts in JNDI? Could this change be made for compatibility with 4.2.x.GA?

      An alternative solution for me could be to be able to create this JNDI context "persistence-units" before the Persistence Units are deployed, but where would I do this?

      If a JBoss Developer or Expert can comment on this one I'd appreciate it.