我正在开发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&#34)
。我知道我可以解压缩EAR和JAR文件以手动编辑persistence.xml等文件,但我不能对已经使用@Resource注释的类执行此操作。
有没有办法可以将我的编译应用程序部署到GlassFish和WildFly上,而无需维护两个不同版本的代码?我假设答案可能取决于特定于应用程序的部署描述符,但我找不到涵盖这两种情况的任何示例。
有人能指出我正确的方向吗?
答案 0 :(得分:4)
您可以修改Wildfly JNDi名称并从相应的JNDI名称中删除不需要的前缀,以找到两个应用服务器中的最小公分母。以下适用于Glassfish和JBoss AS 7.1。由于我希望Wildfly在这方面与JBoss向后兼容,我想它也适用于Wildfly。
注入:
@PersistenceContext(unitName="TestPU")
private EntityManager entityManager;
或通过ejb-jar.xml
:
<persistence-context-ref>
<persistence-context-ref-name>entityManager</persistence-context-ref-name>
<persistence-unit-name>TestPU</persistence-unit-name>
<injection-target> ... </injection-target>
</persistence-context-ref>
相应的persistence.xml
:
<persistence version="2.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_2_0.xsd">
<persistence-unit name="TestPU" transaction-type="JTA">
<jta-data-source>datasources/TestDS</jta-data-source>
<class>org.jeeventstore.persistence.jpa.EventStoreEntry</class>
<properties>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
<property name="hibernate.connection.charSet" value="UTF-8"/>
<property name="eclipselink.logging.level" value="FINE"/>
<property name="eclipselink.logging.level.sql" value="FINE"/>
<property name="eclipselink.logging.parameters" value="true"/>
<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
</properties>
</persistence-unit>
</persistence>
(请注意简单的jta-data-source
JNDI名称)
这里有一个用于在部署时指定Derby数据库的glassfish-resources.xml
文件,类似的设置可以用于MySQL或Postgres。
<resources>
<jdbc-resource pool-name="ArquillianEmbeddedDerbyPool"
jndi-name="datasources/TestDS"/>
<jdbc-connection-pool name="ArquillianEmbeddedDerbyPool"
res-type="javax.sql.DataSource"
datasource-classname="org.apache.derby.jdbc.EmbeddedDataSource"
is-isolation-level-guaranteed="false">
<property name="databaseName" value="target/databases/derby"/>
<property name="createDatabase" value="create"/>
</jdbc-connection-pool>
</resources>
来自JBoss standalone.xml
的设置:
<datasource jta="true" jndi-name="java:/datasources/TestDS" pool-name="TestDS" enabled="true" use-ccm="false">
<connection-url>jdbc:postgresql://localhost/test_db</connection-url>
...
</datasource>
我没有在Glassfish上注入JavaMail组件,但是类似于datasoruce设置,可能值得尝试剥离&#34; java:
&#34;部分来自@Resource
注释。
@Resource(name = "mail/myMailSession")
然后配置Wildfly,以便邮件资源在&#34; java:mail/myMailSession
&#34; JNDI的位置。
ejb-jar.xml
另一种选择是通过ejb-jar.xml
文件手动注入字段,然后使用maven等构建工具将ejb-jar-glassfish.xml
或ejb-jar-wildfly.xml
复制到所需的{{1}在汇编时。
在我们的一个项目中,我们使用混合方法来避免xml配置的负担:我们配置了少量的&#34;提供商&#34; bean通过ejb-jar.xml
将持久化上下文注入ejb-jar.xml
,然后使用CDI通过PersistenceContextProvider
将PersistenceContextProvider
注入到EJB中,这些都是在没有进一步发现的情况下发现的配置,因为它们位于同一个EAR中。
答案 1 :(得分:1)
我还没有遇到邮件困境。但是我遇到了与数据源定义相同的问题,而我的解决方案是不使用服务器控制台设置数据源,而是使用@DataSourceDefinition
注释使它们与归档一起部署。事实证明,如果在部署期间设置了数据源,WildFly不会抱怨java:app/blabla..
。
以下是适用于GlassFish和WildFly的真实世界示例:
https://github.com/martinanderssondotcom/java-ee-concepts/../ArquillianDS.java
请注意,声明的数据源JNDI名称为:
的java:应用程序/ ENV / ArquillianDS
这是相关的persistence.xml
文件(不介意此存储库中文件的名称,存储库代表在运行时构建存档的测试项目,应用程序将更改文件的名称归档到persistence.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驱动程序。
答案 2 :(得分:0)
对于带有可移植DataSourceDefinition注释的JNDI可移植性,我在payara-5.192,wildfly-17.0.1,tomee-8-M3和openLiberty-19.0.0.7上对其进行了测试
@DataSourceDefinition(
name = "java:app/env/jdbc/mysql_app_name",
className = "com.mysql.cj.jdbc.MysqlConnectionPoolDataSource",
url = "jdbc:mysql://localhost:3306/db_name?characterEncoding=utf-8&zeroDateTimeBehavior=CONVERT_TO_NULL&user=root&password=password",
minPoolSize = 1,
properties = {"characterEncoding=utf-8","zeroDateTimeBehavior=CONVERT_TO_NULL"})
我将它与MySQL连接器8一起使用。 请参阅reference。对于wildfly,我创建了用于配置的启动bean类,并在启动类中设置了注释。 对于openLiberty,请在server.xml中添加
<application id="app_name" contextRoot="/app_name" name="app_name" location="../app_name.war" type="war">
<classloader commonLibraryRef="mysql"/>
</application>
<library id="mysql">
<file name="/path_to/mysql-connector-java-8.0.17.jar"/>
</library>
并将战争文件放入
usr / servers / defaultServer
文件夹