The meaning of NoInitialContextException error

I am writing a client for my EJB and when trying to execute it, I get the following exception :

javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file.

I just can't understand what the problem is.

241434 次浏览

Is a JNDI problem. You will see that exception if the InitialContext class has neither default properties for the JNDI service provider nor explicitly configured server properties.

Set the Context.INITIAL_CONTEXT_FACTORY environment property to the class name of the initial context implementation that you are using. This class must be available to your program in the classpath.

Check:

you need to put the following name/value pairs into a hash table and call this constructor:

public InitialContext(Hashtable<?,?> environment)

the exact values depend on your application server, this example is for jboss

jndi.java.naming.provider.url=jnp://localhost:1099/
jndi.java.naming.factory.url=org.jboss.naming:org.jnp.interfaces
jndi.java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory

The javax.naming package comprises the JNDI API. Since it's just an API, rather than an implementation, you need to tell it which implementation of JNDI to use. The implementations are typically specific to the server you're trying to talk to.

To specify an implementation, you pass in a Properties object when you construct the InitialContext. These properties specify the implementation to use, as well as the location of the server. The default InitialContext constructor is only useful when there are system properties present, but the properties are the same as if you passed them in manually.

As to which properties you need to set, that depends on your server. You need to hunt those settings down and plug them in.

Most of the time these settings are also defined in a jndi.properties file. Do you have that one lying around somewhere?

My problem with this one was that I was creating a hibernate session, but had the JNDI settings for my database instance wrong because of a classpath problem. Just FYI...

make sure dependencies for jetty naming and jetty plus are included (not just provided scope). This fixed it for me.

You should set jndi.properties. I've given below some piece of code that explain how the properties are set for activemq. Like that you can set for your application. Inside a J2EE container like JBoss no need to set these properties.

Properties props = new Properties();
props.setProperty(Context.INITIAL_CONTEXT_FACTORY,"org.apache.activemq.jndi.ActiveMQInitialContextFactory");
props.setProperty(Context.PROVIDER_URL,"tcp://localhost:61616");
InitialContext ctx = new InitialContext(props);
// get the initial context
// InitialContext ctx = new InitialContext();
QueueConnectionFactory connFactory = (QueueConnectionFactory) ctx.lookup("ConnectionFactory");
// create a queue connection
QueueConnection queueConn = connFactory.createQueueConnection();
queueConn.start();
// lookup the queue object
Queue queue = (Queue) ctx.lookup("dynamicQueues/Payment_Check");

I know this is a late answer, but just giving for future reference.

I solved the same problem by adding the following Jar libraries to my project:

  • appserv-rt.jar
  • javaee.jar

from the folder : C:\Program Files\glassfish-4.0\glassfish\lib

The links to these libraries were broken and Netbeans didn't found the right classes to use.

Easy & configurable solution is create one jndi.properties file and put this file in classpath. jndi.properties can be created as

java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory


# use the following property to configure the default connector
java.naming.provider.url = vm://localhost


# use the following property to specify the JNDI name the connection factory
# should appear as.
#connectionFactoryNames = connectionFactory, queueConnectionFactory, topicConnectionFactry


# register some queues in JNDI using the form
# queue.[jndiName] = [physicalName]
queue.MyQueue = example.MyQueue




# register some topics in JNDI using the form
# topic.[jndiName] = [physicalName]
topic.MyTopic = example.MyTopic

Just specify your naming factory & url and put this file in your classpath. JMS will fetch required info by itself and it's easily configurable in future also.

Do this:

Properties props = new Properties();
props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.enterprise.naming.SerialInitContextFactory");
Context initialContext = new InitialContext(props);

Also add this to the libraries of the project:

C:\installs\glassfish\glassfish-4.1\glassfish\lib\gf-client.jar adjust path accordingly

Specifically, I got this issue when attempting to retrieve the default (no-args) InitialContext within an embedded Tomcat7 instance, in SpringBoot.

The solution for me, was to tell Tomcat to enableNaming.

i.e.

@Bean
public TomcatEmbeddedServletContainerFactory tomcatFactory() {
return new TomcatEmbeddedServletContainerFactory() {
@Override
protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(
Tomcat tomcat) {
tomcat.enableNaming();
return super.getTomcatEmbeddedServletContainer(tomcat);
}
};
}

you need to use jboss-client.jar in your client project and you need to use jnp-client jar in your ejb project

Try adding rmi java modules in you runtime environment : --add-modules jdk.naming.rmi,java.base