如何使JNDI名称与GlassFish和WildFly兼容

我正在开发Java EE 7应用程序,并且要求将应用程序部署到运行GlassFish 4.0或WildFly 8.1.0的应用程序服务器上。 我遇到的问题是GlassFish和WildFly对JNDI名称使用略有不同的格式,但我看不出如何使我的应用程序兼容两者。

在GlassFish中,我的persistence.xml文件引用数据源jdbc / myDataSouce,但在WildFly中,数据源需要是java:/ jdbc / myDataSource。

对于使用@Resource注释的类也是如此。 在GlassFish中,使用JavaMail的类的注释将是@Resource(name =“mail / myMailSession”),但要部署到WildFly,这需要是@Resource(name =“java:mail / myMailSession”)。

我知道我可以解压缩EAR和JAR文件以手动编辑文件,例如persistence.xml,但我不能对已经使用@Resource注释的类执行此操作。

有没有办法可以将我的编译应用程序部署到GlassFish和WildFly上,而无需维护两个不同版本的代码? 我假设答案可能取决于特定于应用程序的部署描述符,但我找不到任何涵盖这两种情况的示例。

有人能指出我正确的方向吗?

您可以修改Wildfly JNDi名称并从相应的JNDI名称中删除不需要的前缀,以查找两个应用程序服务器中的最小公分母。 以下适用于Glassfish和JBoss AS 7.1。 由于我希望Wildfly在这方面与JBoss向后兼容,我想它也适用于Wildfly。

坚持

注入:

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

或者通过ejb-jar.xml

  entityManager TestPU  ...   

相应的persistence.xml

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

(注意简单的jta-data-source JNDI名称)

这是一个glassfish-resources.xml文件,用于在部署时指定Derby数据库,类似的设置可用于MySQL或Postgres。

        

以及JBoss standalone.xml的设置:

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

资源

我没有在Glassfish上注入JavaMail组件,但是类似于datasoruce设置,尝试从@Resource注释中剥离“ java: ”部分也是值得的。

 @Resource(name = "mail/myMailSession") 

然后配置Wildfly,以便邮件资源在“ java:mail/myMailSession ”JNDI位置可用。

通过ejb-jar.xml注入

另一个选择是通过ejb-jar.xml文件手动注入字段,然后使用maven等构建工具将ejb-jar-glassfish.xmlejb-jar-wildfly.xml中的任何一个复制到所需的ejb-jar.xml汇编时的ejb-jar.xml

在我们的一个项目中,我们使用混合方法来避免xml配置的负担:我们通过ejb-jar.xml配置少量“提供者”bean,例如将持久化上下文注入到PersistenceContextProvider ,然后使用CDI通过@EJBPersistenceContextProvider注入EJB,无需进一步配置即可找到它们,因为它们位于同一个EAR中。

我还没有遇到邮件困境。 但是我遇到了与数据源定义相同的问题,而我的解决方案是不使用服务器控制台设置数据源,而是使用@DataSourceDefinition批注将它们与归档一起部署。 事实certificate,如果在部署期间设置了数据源,WildFly不会抱怨java:app/blabla..

以下是适用于GlassFish和WildFly的真实世界示例:

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

请注意,声明的数据源JNDI名称是:

Java的:应用程序/ ENV / ArquillianDS

这里是相关的persistence.xml文件(不介意此存储库中文件的名称,存储库代表在运行时构建存档的测试项目,应用程序将更改存档中文件的名称为持久性。 XML):

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

另请注意,持久性单元需要使用此JNDI名称定位的数据源:

Java的:应用程序/ ENV / ArquillianDS

这种部署与GlassFish和WildFly完美配合。 我已经注意到,如果我们在部署期间声明数据源,那么我们付出的代价就是没有看到admin gui / console中任何地方列出的数据源。 对我来说,这是一个很小的代价,以便有一个真正的便携式应用程序。 作为额外的奖励,我不必编写冗长的安装/设置说明。 对于我的所有项目,数据源是应用程序的固有部分,我不介意在存档中有一个表示数据源的类文件。

上述数据源使用的是Java DB(或旧式学校的“Apache Derby”)。 正如ArquillianDS.java文件中的一些注释所描述的那样:GlassFish在使用简单的URL连接字符串和Java DB时遇到了问题。 因此,我使用了明确指定@DataSourceDefinition所有属性。 最近在我的另一个项目(唉不是公共项目)中,我使用了相同的部署时间数据源定义结构,但是针对MySQL。 这是数据源定义,它适用于两个服务器:

 @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 { } 

请注意,驱动程序是MysqlDataSource而不是MysqlXADataSource 。 我的应用程序中的一点使用了相当复杂的事务方案,如果我使用XA驱动程序,GlassFish会遇到问题。 但是,我的应用程序使用的非XA驱动程序仍然可以正常使用JTA事务,所以对我来说,这只是一个让船浮动的廉价技巧。 您应该使用XA驱动程序。