83

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.

Mike
  • 14,010
  • 29
  • 101
  • 161
Attilah
  • 17,632
  • 38
  • 139
  • 202

13 Answers13

38

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.

skaffman
  • 398,947
  • 96
  • 818
  • 769
18

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.

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
nichu09
  • 882
  • 2
  • 15
  • 44
15

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
Mike
  • 14,010
  • 29
  • 101
  • 161
stacker
  • 68,052
  • 28
  • 140
  • 210
11

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:

Mike
  • 14,010
  • 29
  • 101
  • 161
JuanZe
  • 8,007
  • 44
  • 58
  • thx for the pointer, how can I solve it ? I'm new to this J2EE stuff. – Attilah Oct 06 '09 at 13:12
  • Is not a question for a quick answer. Depends on your application server stuff. I suggest you check the documentation for the app server you are using and try to run a Hello World EJB app on your plataform to get deeper understanding of the topic. – JuanZe Oct 06 '09 at 13:23
10

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);
        }
    };
}
Nick Grealy
  • 24,216
  • 9
  • 104
  • 119
  • 1
    In spring boot 2 the package org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedServletWebServerFactory has been replaced by org.springframework.boot.web.embedded.tomcat.ConfigurableTomcatWebServerFactory how do i implement with the new interface? – Adindu Stevens Aug 22 '19 at 14:41
  • @AdinduStevens - no idea. I provided this solution 3 years ago, and haven't touched Spring since. You'll have to do your own research. – Nick Grealy Aug 23 '19 at 01:20
  • @Adindu Stevens I face the same problem with spring boot 2, did you find any solution for it? – itro Apr 22 '20 at 08:31
  • @itro try this https://stackoverflow.com/questions/24941829/how-to-create-jndi-context-in-spring-boot-with-embedded-tomcat-container/53457808#53457808 – Delirante Jan 05 '21 at 10:52
5

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.

Vaibhav Jain
  • 1,939
  • 26
  • 36
3

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

2

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.

Kevin Panko
  • 8,356
  • 19
  • 50
  • 61
Yannickv
  • 527
  • 4
  • 13
1

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

Sangram Badi
  • 4,054
  • 9
  • 45
  • 78
1

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...

Thom
  • 14,013
  • 25
  • 105
  • 185
0

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

Neocy
  • 166
  • 2
0

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

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
ACV
  • 9,964
  • 5
  • 76
  • 81
0

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

  • 1
    If you are unsure about the solution you propose for experiemnt then please phrase this as an explained conditional answer, in order to avoid the impression of asking a clarification question instead of answering (for which a comment should be used instead of an answer, compare https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead ). For example like "If your problem is ... then the solution is to .... because .... ." – Yunnosch Jun 28 '22 at 06:03
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jun 28 '22 at 12:11