Como faço para tornar os nomes JNDI compatíveis com o GlassFish e o WildFly?

Estou desenvolvendo um aplicativo Java EE 7 e tenho um requisito para que o aplicativo seja implantado em servidores de aplicativos que executam o GlassFish 4.0 ou o WildFly 8.1.0. O problema que tenho é que o GlassFish e o WildFly usam formatos ligeiramente diferentes para os nomes JNDI, mas não consigo ver como tornar meu aplicativo compatível com ambos.

No GlassFish meu arquivo persistence.xml faz referência à fonte de dados jdbc / myDataSouce, mas no WildFly a origem de dados precisa ser java: / jdbc / myDataSource.

O mesmo também é verdadeiro para classs que são anotadas com @Resource. No GlassFish, a anotação para uma class usando JavaMail seria @Resource (name = “mail / myMailSession”), mas para implantar no WildFly isso precisaria ser @Resource (name = “java: mail / myMailSession”).

Eu sei que eu poderia descompactar os arquivos EAR e JAR para editar manualmente arquivos como persistence.xml, mas não posso fazer isso para classs que foram anotadas com @Resource.

Existe uma maneira que eu possa permitir que meu aplicativo seja implantado no GlassFish e no WildFly sem manter duas versões diferentes do código? Estou assumindo que a resposta provavelmente está nos descritores de implantação específicos do aplicativo, mas não consigo encontrar nenhum exemplo que cubra esses dois cenários.

Alguém poderia indicar-me a direção correta, por favor?

Você pode modificar os nomes do Wildfire JNDi e remover os prefixos indesejados dos respectivos nomes JNDI para encontrar o mínimo denominador comum em ambos os servidores de aplicativos. O seguinte funciona para mim com o Glassfish e o JBoss AS 7.1. Já que eu espero que o Wildfly seja compatível com o JBoss, eu acho que ele funcionará para o Wildfly também.

Persistência

Injetar como:

@PersistenceContext(unitName="TestPU") private EntityManager entityManager; 

ou via ejb-jar.xml :

  entityManager TestPU  ...   

O persistence.xml correspondente:

   datasources/TestDS org.jeeventstore.persistence.jpa.EventStoreEntry             

(observe o nome JNDI simples da jta-data-source )

Aqui está um arquivo glassfish-resources.xml usado para especificar um database Derby na implementação, uma configuração similar pode ser usada para MySQL ou Postgres.

        

E as configurações do standalone.xml do JBoss:

  jdbc:postgresql://localhost/test_db ...  

Recursos

Eu não injetou um componente JavaMail no Glassfish, mas similar às configurações de datasoruce, pode valer a pena tentar remover também a parte ” java: ” da anotação @Resource .

 @Resource(name = "mail/myMailSession") 

e configure o Wildfly de forma que o recurso de correio esteja disponível no local JNDI ” java:mail/myMailSession “.

Injeção via ejb-jar.xml

Outra opção é injetar manualmente os campos por meio de um arquivo ejb-jar.xml e, em seguida, usar uma ferramenta de compilation, como maven, para copiar o ejb-jar-glassfish.xml ou o ejb-jar-wildfly.xml para o ejb-jar.xml no tempo de assembly.

Em um de nossos projetos, usamos uma abordagem mista para evitar a sobrecarga da configuração xml: configuramos um pequeno número de beans “provider” via ejb-jar.xml para injetar, por exemplo, o contexto de persistência em um PersistenceContextProvider e, em seguida, CDI para injetar o PersistenceContextProvider nos EJBs via @EJB , que são encontrados sem configuração adicional, pois residem no mesmo EAR.

Ainda não cheguei ao dilema do correio. Mas enfrentei o mesmo problema que você tem quando se trata de definição de fonte de dados e minha solução tem sido não configurar as fonts de dados usando o console do servidor, mas torná-las implantáveis ​​junto com seu arquivo usando a anotação @DataSourceDefinition . Acontece que o WildFly não vai reclamar sobre o java:app/blabla.. se a fonte de dados estiver configurada durante a implementação!

Aqui está um exemplo do mundo real para você que funciona tanto no GlassFish quanto no WildFly:

https://github.com/martinanderssondotcom/java-ee-concepts/../ArquillianDS.java

Observe que o nome JNDI da origem de dados declarado é:

java: app / env / ArquillianDS

E aqui está o arquivo persistence.xml relacionado (não importa o nome do arquivo neste repository, o repository representa um projeto de teste que constrói arquivos durante o tempo de execução e o aplicativo irá alterar o nome do arquivo no archive para persistência. xml):

https://github.com/MartinanderssonDotcom/java-ee-concepts/../persistence-update.xml

Observe também que a unidade de persistência precisa de uma fonte de dados localizada usando esse nome da JNDI:

java: app / env / ArquillianDS

Esta implantação funciona perfeitamente com o GlassFish e o WildFly. Observei que, se declararmos a fonte de dados durante a implantação, pagaremos o preço de não ver a fonte de dados listada em qualquer lugar no console / console de administração. Para mim, esse é um pequeno preço a pagar para ter um aplicativo verdadeiramente portátil. Como um bônus adicional, eu não tenho que escrever longas instruções de instalação / configuração. Para todos os meus projetos, a fonte de dados é uma parte intrínseca do aplicativo e não me importo de ter um arquivo de class no arquivo morto que represente a fonte de dados.

A fonte de dados acima está usando um Java DB (ou “Apache Derby” para pessoas da velha escola). Como alguns comentários no arquivo ArquillianDS.java descrevem: O GlassFish tem problemas ao usar uma cadeia de conexão de URL simples combinada com o Java DB. Por isso, recorri a especificar explicitamente todos os atributos da @DataSourceDefinition . Recentemente, em outro projeto meu (infelizmente não público), usei a mesma construção de definição de fonte de dados de tempo de implementação, mas direcionando o MySQL. Aqui está a definição da fonte de dados e funciona nos dois servidores:

 @DataSourceDefinition( name = "java:app/env/maLivechatDS", url = "jdbc:mysql://localhost:3306/malivechat_db?createDatabaseIfNotExist=true&user=root&password", className = "com.mysql.jdbc.jdbc2.optional.MysqlDataSource" ) @ManagedBean public class MySQLDataSource { } 

Observe que o driver é MysqlDataSource e não MysqlXADataSource . Um ponto no meu aplicativo usa um esquema de transação bastante complexo e o GlassFish teve problemas se eu usei o driver XA. No entanto, o driver não-XA usado pelo meu aplicativo ainda funciona corretamente com as transactions do JTA, então, para mim, era apenas um truque barato para fazer o barco flutuar. Você provavelmente deveria usar o driver XA.