JPA com JNDI e Toplink na Locaweb

3 respostas
G

Estou tentando usar a JPA da Toplink com uma coneção por JNDI configurada pela Locaweb e não funciona. Minha aplicação não reconhece de forma alguma o “nome” de jndi que me passaram.

Reclamei em um chamado e responderam que a configuração realmente estava errada. :x Corrigiram e fizeram um teste na minha área com uma conexão em JSP que funciona:

Context context = new InitialContext();
Context lautx = (Context) context.lookup("java:comp/env");
ds = (DataSource)lautx.lookup("jdbc/jndiname");
conexao = ds.getConnection();
out.write("Conectado via JNDI!<br><br>");
Statement stmt= conexao.createStatement();
conexao.close();

Mas eu preciso que funcione com JPA… Aqui na minha máquina funciona (tomcat configurado por mim)
Alguém sabe se tem algum outro macete que preciso configurar para conseguir usar a persistência por JPA? :?: :?:
Minha configuração por JPA:

&lt;persistence-unit name="newsPU" transaction-type="JTA"&gt;
    &lt;provider&gt;oracle.toplink.essentials.PersistenceProvider&lt;/provider&gt;
    &lt;jta-data-source&gt;jdbc/jndiname&lt;/jta-data-source&gt;
    &lt;properties/&gt;
  &lt;/persistence-unit&gt;

Erro que aparece no log:

Caused by: javax.persistence.PersistenceException: Exception [TOPLINK-7060] 
(Oracle TopLink Essentials - 9.1 (Build b27)): oracle.toplink.esse
ntials.exceptions.ValidationException
Exception Description: Cannot acquire data source [jdbc/jndiname].
Internal Exception: javax.naming.NameNotFoundException: Name jdbc is not bound in this Context
        at oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerSetupImpl.deploy
(EntityManagerSetupImpl.java:180)    at oracle.toplink.essentials.internal.ejb.cmp3.base.
EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:78)        at oracle.toplink.essentials.internal.ejb.cmp3.base.EntityManagerFactoryImpl.createEntityManagerImpl
(EntityManagerFactoryImpl.java:113
)

A propósito, tenho JVM dedicado.

3 Respostas

F

Minha experiência com a locaweb não foi nada boa, sempre tive problemas parecidos com o seu.
As vezes levava dias para conseguir depurar o problema e mais dias para conseguir que alguém resolvesse. Por isto que agora o PJ é hospedado pela RoseHosting, que eu recomendo.

Eu não sei como é este plano novo, de JVM dedicada, mas como você escreveu “a jndi que me passaram” eu imagino que o suporte da Locaweb ainda seja responsável por algumas configurações, provavelmente para não haver conflito de nomes na mesma rede.

Eu não entendi porque o suporte precisa configurar o nome do serviço pra você, se teoricamente você, o plano oferece JVM dedicada e você poderia rodar o tomcat (ou outro) neste JVM. Não pode?

O meu conselho, apesar de não ajudar muito, é você colocar uma classe de teste que sobe um serviço JNDI e depois tentar “encontrá-lo”. Se isto não funcionar, a Locaweb tá fazendo algum tipo de restrição na rede ou na API de redes das JVMs.

G

Consegui!
Eu realmente quase saí da Locaweb... Mas um atendente do help desk hoje ligou em meu cel e eu o ajudei a configurar a JNDI corretamente no tomcat, hehehe

Mesmo assim tive que criar uma outra classe para a sessão da Toplink.

O HelpDesk da Locaweb me ajudou a encontrar a solução, no fórum da Oracle http://kr.forums.oracle.com/forums/thread.jspa?threadID=519351&tstart=127

Tenho que criar uma classe para prover a sessão de login:
public class ToplinkSessionCustomizer implements SessionCustomizer {

	/**
	 * Construtor
	 */
	public ToplinkSessionCustomizer() {
		super();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see oracle.toplink.essentials.tools.sessionconfiguration.SessionCustomizer#customize(oracle.toplink.essentials.sessions.Session)
	 */
	public void customize(Session session) throws Exception {
		JNDIConnector connector = (JNDIConnector) session.getLogin()
				.getConnector();
		connector.setLookupType(JNDIConnector.STRING_LOOKUP);
	}
}

E em meu persistence.xml:

&lt;persistence-unit name="newsPU" transaction-type="JTA"&gt;
		&lt;provider&gt;
			oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider
		&lt;/provider&gt;
		&lt;jta-data-source&gt;java:comp/env/jdbc/jndiname&lt;/jta-data-source&gt;
&lt;properties&gt;
			&lt;property name="toplink.session.customizer" value="a.b.c.ToplinkSessionCustomizer" /&gt;

Pronto, a jndi é encontrada!

Vale lembrar que tudo isso é porque a Locaweb que configura a JNDI no tomcat deles... O ideal é fazer um arquivo de contexto e configurar na aplicação.

L

Oi,

estou com o mesmo problema porém ainda não consegui resolver, mesmo realizando os procedimentos informados.

public class testeclass {

    public static EntityManagerFactory emf = Persistence.createEntityManagerFactory("ReservaPassagensEJBPU2");
    
    public void persist(Object object) {
        try {
            EntityManager em = null;
            
            em = emf.createEntityManager();
            em.getTransaction().begin();
            
            em.persist(object);
            
            em.getTransaction().commit();
            
        } catch (Exception e) {
            java.util.logging.Logger.getLogger(getClass().getName()).log(java.util.logging.Level.SEVERE, "exception caught", e);
            throw new RuntimeException(e);
        }
    }

}
public class ToplinkSessionCustomizer implements SessionCustomizer {
    public ToplinkSessionCustomizer() {   
        super();   
    }  
    
    public void customize(Session session) throws Exception{
        JNDIConnector connector = (JNDIConnector) session.getLogin().getConnector();
        connector.setLookupType(JNDIConnector.STRING_LOOKUP);
    }
}

Minha persistence.xml está da seguinte forma:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
  <persistence-unit name="ReservaPassagensEJBPU2" transaction-type="JTA">
    <provider>oracle.toplink.essentials.PersistenceProvider</provider>
    <jta-data-source>SistResevaBanco</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
      <property name="toplink.session.customizer" value="br.com.reserva.teste.ToplinkSessionCustomizer"/>
    </properties>
  </persistence-unit>
</persistence>

na linha

em = emf.createEntityManager();

e está me gerando o seguinte erro:

21/11/2008 21:18:59 br.com.reserva.teste.testeclass persist
SEVERE: exception caught
javax.persistence.PersistenceException: Exception [TOPLINK-7060] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.ValidationException
Exception Description: Cannot acquire data source [SistResevaBanco].
Internal 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:  java.naming.factory.initial
        at oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:239)
        at oracle.toplink.essentials.internal.ejb.cmp3.base.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:93)
        at oracle.toplink.essentials.internal.ejb.cmp3.base.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:126)
        at oracle.toplink.essentials.internal.ejb.cmp3.base.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:120)
        at oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:91)
        at br.com.reserva.teste.testeclass.persist(testeclass.java:24)
        at br.com.reserva.teste.testaEJB.main(testaEJB.java:36)
Caused by: Exception [TOPLINK-7060] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.ValidationException
Exception Description: Cannot acquire data source [SistResevaBanco].
Internal 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:  java.naming.factory.initial
        at oracle.toplink.essentials.exceptions.ValidationException.cannotAcquireDataSource(ValidationException.java:373)
        at oracle.toplink.essentials.jndi.JNDIConnector.connect(JNDIConnector.java:135)
        at oracle.toplink.essentials.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:184)
        at oracle.toplink.essentials.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:582)
        at oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:280)
        at oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:229)
        ... 6 more
Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
        at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:645)
        at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
        at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:325)
        at javax.naming.InitialContext.lookup(InitialContext.java:392)
        at oracle.toplink.essentials.jndi.JNDIConnector.connect(JNDIConnector.java:127)
        ... 10 more
java.lang.RuntimeException: javax.persistence.PersistenceException: Exception [TOPLINK-7060] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.ValidationException
Exception Description: Cannot acquire data source [SistResevaBanco].
Internal 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:  java.naming.factory.initial
        at br.com.reserva.teste.testeclass.persist(testeclass.java:33)
        at br.com.reserva.teste.testaEJB.main(testaEJB.java:36)
Caused by: javax.persistence.PersistenceException: Exception [TOPLINK-7060] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.ValidationException
Exception Description: Cannot acquire data source [SistResevaBanco].
Internal 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:  java.naming.factory.initial
        at oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:239)
        at oracle.toplink.essentials.internal.ejb.cmp3.base.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:93)
        at oracle.toplink.essentials.internal.ejb.cmp3.base.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:126)
        at oracle.toplink.essentials.internal.ejb.cmp3.base.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:120)
        at oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:91)
        at br.com.reserva.teste.testeclass.persist(testeclass.java:24)
        ... 1 more
Caused by: Exception [TOPLINK-7060] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.ValidationException
Exception Description: Cannot acquire data source [SistResevaBanco].
Internal 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:  java.naming.factory.initial
        at oracle.toplink.essentials.exceptions.ValidationException.cannotAcquireDataSource(ValidationException.java:373)
        at oracle.toplink.essentials.jndi.JNDIConnector.connect(JNDIConnector.java:135)
        at oracle.toplink.essentials.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:184)
        at oracle.toplink.essentials.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:582)
        at oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:280)
        at oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:229)
        ... 6 more
Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
        at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:645)
        at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
        at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:325)
        at javax.naming.InitialContext.lookup(InitialContext.java:392)
        at oracle.toplink.essentials.jndi.JNDIConnector.connect(JNDIConnector.java:127)
        ... 10 more

fico no aguardo,

Obrigado

Criado 21 de junho de 2008
Ultima resposta 21 de nov. de 2008
Respostas 3
Participantes 3