我正在尝试学习如何分离java EE组件。
我想将我的jpa实体,ejbs和Web客户端分成不同的项目
所以我开发了四个不同的项目,并在他们自己的罐子/战争中编译它们
DomainEntities的jar结构是
DomainEntities
-META-INF
-MANIFEST.MF
-entities
-Student.class
RemoteEJB的jar结构是
RemoteEJB
-META-INF
-MANIFEST.MF
-persistence.xml
-sample
MyStatelessBean.class
RemoteEJB中的persistence.xml是(基于搜索网络):
<?xml version="1.0" encoding="UTF-8"?> <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="RemoteEJBPU" transaction-type="JTA"><provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/pwucdb</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<!--<jar-file>DomainEntities.jar</jar-file>-->
</persistence-unit>
</persistence>
jta数据源在我的glassfish服务器中定义。 exclude-unlisted-classes和jar-file标签基于我在不同jar上分离jpa实体的研究。当我取消注释jar文件标签时,ejb无法部署到服务器,所以我对它进行评论。
调用的servlet使用ejb是:
@WebServlet(name = "NewServlet", urlPatterns = {"/NewServlet"})
public class NewServlet extends HttpServlet {
@EJB
private MyRemoteInterface myRemoteInterface;
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
try (PrintWriter out = response.getWriter()) {
out.println(myRemoteInterface.getMessage());
out.println("Num of records retrived: " + myRemoteInterface.getStudents().size());
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
}
当我尝试访问servlet时,我遇到此警告/错误
WARNING: The collection of metamodel types is empty. Model classes may not have been found during entity search for Java SE and some Java EE container managed persistence units. Please verify that your entity classes are referenced in persistence.xml using either <class> elements or a global <exclude-unlisted-classes>false</exclude-unlisted-classes> element
WARNING: A system exception occurred during an invocation on EJB MyStatelessBean method public java.util.List sample.MyStatelessBean.getStudents()
javax.ejb.EJBException
.....
Caused by: java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager:
Exception Description: Error compiling the query [SELECT s FROM Student s]. Unknown entity type [Student].
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1477)
如果我注释掉exclude-unlisted-classes标记,则取消注释jar-file标记并进行部署。我得到这个服务器警告:
a jar-file [DomainEntities.jar] specified in persistence.xml is not found
The server also looked for a file called [...\build\DomainEntities_jar].
答案 0 :(得分:1)
我建议将JAR和WAR捆绑到EAR-Archive中。 如果你使用maven,你可以将这个插件添加到EAR的pom:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>2.8</version>
<configuration>
<version>6</version>
<encoding>${project.build.sourceEncoding}</encoding>
<defaultLibBundleDir>APP-INF/lib</defaultLibBundleDir>
<fileNameMapping>no-version</fileNameMapping>
<displayName>${project.artifactId}</displayName>
<modules>
<jarModule>
<groupId>${project.groupId}</groupId>
<artifactId>domain</artifactId>
</jarModule>
<ejbModule>
<groupId>${project.groupId}</groupId>
<artifactId>ejb</artifactId>
</ejbModule>
</modules>
</configuration>
</plugin>
因此,EAR的所有库将被复制到/ APP-INF / lib中。 在此范围内,现在可以从EJB视图访问它。只需将其称为:
<jar-file>APP-INF/lib/domain.jar</jar-file>
注意
<fileNameMapping>no-version</fileNameMapping>
如果你想经常更改你的域存档的版本,这非常重要,否则你必须一直编辑EJB的persistence.xml;)
一些补充:
如果将所有内容捆绑到EAR-Archive中,则不再需要使用远程接口。你只需要本地接口。这是一件好事,因为通过远程接口访问EJB比使用本地接口访问它要慢得多。那是因为Java序列化所有对象以通过网络发送它们。