Erro NoInitialContextException

Estou escrevendo um cliente para o meu EJB e ao tentar executá-lo, recebo a seguinte exceção:

javax.naming.NoInitialContextException: Precisa especificar o nome da class no ambiente ou na propriedade do sistema, ou como um parâmetro do applet ou em um arquivo de resources do aplicativo.

Eu simplesmente não consigo entender qual é o problema.

O pacote javax.naming compreende a API JNDI. Como é apenas uma API, em vez de uma implementação, é necessário informar qual implementação do JNDI deve ser usada. As implementações são tipicamente específicas para o servidor com o qual você está tentando conversar.

Para especificar uma implementação, você passa um object Properties ao construir o InitialContext . Essas propriedades especificam a implementação a ser usada, bem como a localização do servidor. O construtor InitialContext padrão é útil somente quando há propriedades do sistema presentes, mas as propriedades são as mesmas que se você as tivesse passado manualmente.

Quanto às propriedades que você precisa definir, isso depende do seu servidor. Você precisa caçar essas configurações e conectá-las.

você precisa colocar os seguintes pares nome / valor em uma Hashtable e chamar este contructor:

 public InitialContext(Hashtable< ?,?> environment) 

os valores exatos dependem do seu servidor de aplicativos, este exemplo é para 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 

É um problema da JNDI. Você verá essa exceção se a class InitialContext não tiver propriedades padrão para o provedor de serviços JNDI nem configurar propriedades do servidor explicitamente.

Defina a propriedade de ambiente Context.INITIAL_CONTEXT_FACTORY como o nome da class da implementação de contexto inicial que você está usando. Esta class deve estar disponível para o seu programa no caminho de class.

Verifica:

http://docs.oracle.com/javase/7/docs/api/javax/naming/InitialContext.html

http://java.sun.com/products/jndi/tutorial/getStarted/TOC.html (problemas de tempo de execução)

Você deve definir jndi.properties. Eu dei abaixo um pedaço de código que explica como as propriedades são definidas para o ativemq. Assim você pode definir para o seu aplicativo. Dentro de um contêiner J2EE como o JBoss, não é necessário definir essas propriedades.

 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"); 

Eu sei que esta é uma resposta tardia, mas apenas dando para referência futura.

Especificamente, recebi esse problema ao tentar recuperar o InitialContext padrão (sem argumentos) dentro de uma instância do Tomcat7 incorporada, no SpringBoot.

A solução para mim foi dizer ao Tomcat para enableNaming .

ou seja

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

A solução fácil e configurável é criar um arquivo jndi.properties e colocar esse arquivo no classpath. jndi.properties pode ser criado como

 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 

Basta especificar sua fábrica de nomenclatura & url e colocar esse arquivo em seu caminho de class. O JMS buscará as informações necessárias por si só e será facilmente configurável no futuro também.

Na maioria das vezes, essas configurações também são definidas em um arquivo jndi.properties . Você tem esse alguém em algum lugar?

Meu problema com este foi que eu estava criando uma session de hibernação, mas tinha as configurações de JNDI para minha instância de database errado por causa de um problema de caminho de class. Apenas FYI …

Eu resolvi o mesmo problema adicionando as seguintes bibliotecas Jar ao meu projeto:

  • appserv-rt.jar
  • javaee.jar

da pasta: C:\Program Files\glassfish-4.0\glassfish\lib

Os links para essas bibliotecas foram quebrados e o Netbeans não encontrou as classs certas para usar.

Certifique-se de que as dependencies para nomeação de jetty e jetty plus estejam incluídas (não apenas o escopo fornecido). Isso consertou para mim.

Faça isso:

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

Além disso, inclua isso nas bibliotecas do projeto:

C:\installs\glassfish\glassfish-4.1\glassfish\lib\gf-client.jar ajusta o caminho de acordo

você precisa usar o jboss-client.jar no seu projeto cliente e você precisa usar o jnp-client jar no seu projeto ejb