是否有一些特定的方法可以确保EJB模块在Netbeans中正确部署到web应用程序?
我将以EJB食谱为例,从servlet调用会话Bean。我清除了Netbeans中的glassfish输出,进行了一次干净的编译并运行:
INFO: visiting unvisited references
INFO: visiting unvisited references
SEVERE: Class [ Lpakt/Salutation; ] not found. Error while loading [ class pakt.SalutationServlet ]
INFO: visiting unvisited references
INFO: Loading application [SalutationApplication-war] at [/SalutationApplication-war]
INFO: SalutationApplication-war was successfully deployed in 382 milliseconds.
INFO: processRequest..
WARNING: StandardWrapperValve[SalutationServlet]: Servlet.service() for servlet SalutationServlet threw exception
java.lang.NoClassDefFoundError: pakt/Salutation
at pakt.SalutationServlet.processRequest(SalutationServlet.java:30)
at pakt.SalutationServlet.doGet(SalutationServlet.java:45)
servlet为什么不加载pakt.Salutation
?
干净的结构(未编译):
SalutationApplication/
├── build.xml
├── nbproject
│ ├── ant-deploy.xml
│ ├── build-impl.xml
│ ├── genfiles.properties
│ ├── private
│ │ └── private.properties
│ ├── project.properties
│ └── project.xml
├── SalutationApplication-ejb
│ ├── build.xml
│ ├── nbproject
│ │ ├── ant-deploy.xml
│ │ ├── build-impl.xml
│ │ ├── genfiles.properties
│ │ ├── private
│ │ │ └── private.properties
│ │ ├── project.properties
│ │ └── project.xml
│ └── src
│ ├── conf
│ │ └── MANIFEST.MF
│ └── java
│ └── pakt
│ ├── LocalBean.java
│ ├── RemoteBean.java
│ └── Salutation.java
├── SalutationApplication-war
│ ├── build.xml
│ ├── nbproject
│ │ ├── ant-deploy.xml
│ │ ├── build-impl.xml
│ │ ├── genfiles.properties
│ │ ├── private
│ │ │ └── private.properties
│ │ ├── project.properties
│ │ └── project.xml
│ ├── src
│ │ ├── conf
│ │ │ └── MANIFEST.MF
│ │ └── java
│ │ └── pakt
│ │ └── SalutationServlet.java
│ └── web
│ ├── index.html
│ └── WEB-INF
│ └── web.xml
└── src
└── conf
└── MANIFEST.MF
20 directories, 30 files
servlet:
package pakt;
import java.io.IOException;
import java.io.PrintWriter;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(urlPatterns = {"/SalutationServlet"})
public class SalutationServlet extends HttpServlet {
@EJB
private Salutation salutation;
protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
System.out.println("processRequest..");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet SalutationServlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>"
+ salutation.getFormalSalutation("Sherlock Holmes")
+ "</h1>");
out.println("</body>");
out.println("</html>");
} finally {
out.flush();
out.close();
}
}
@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);
}
}
包装包装;
导入javax.ejb.Stateless;导入javax.ejb.LocalBean;
@LocalBean@无状态(mappedName="saltationBean")公共类Salutation实现RemoteBean{
public String getFormalSalutation(String name) {
return "Dear " + name;
}
public String getInformalSalutation(String name) {
return "Hi " + name;
}
@Override
public void myRemote() {
System.out.println("myRemote..");
}
}
web.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<servlet>
<servlet-name>SalutationServlet</servlet-name>
<servlet-class>pakt.SalutationServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SalutationServlet</servlet-name>
<url-pattern>/SalutationServlet</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
</web-app>
-------------------------------------------编辑------------------------------
应用程序的附加结构:
thufir@dur:~$
thufir@dur:~$ tree NetBeansProjects/SalutationApplication
NetBeansProjects/SalutationApplication
├── build
│ ├── META-INF
│ │ └── MANIFEST.MF
│ ├── SalutationApplication-ejb.jar
│ └── SalutationApplication-war.war
├── build.xml
├── dist
│ └── SalutationApplication.ear
├── nbproject
│ ├── ant-deploy.xml
│ ├── build-impl.xml
│ ├── genfiles.properties
│ ├── private
│ │ └── private.properties
│ ├── project.properties
│ └── project.xml
├── SalutationApplication-ejb
│ ├── build
│ │ ├── classes
│ │ │ ├── META-INF
│ │ │ │ └── MANIFEST.MF
│ │ │ └── pakt
│ │ │ ├── Salutation.class
│ │ │ └── SalutationLocal.class
│ │ ├── empty
│ │ └── generated-sources
│ │ └── ap-source-output
│ ├── build.xml
│ ├── dist
│ │ └── SalutationApplication-ejb.jar
│ ├── nbproject
│ │ ├── ant-deploy.xml
│ │ ├── build-impl.xml
│ │ ├── genfiles.properties
│ │ ├── private
│ │ │ └── private.properties
│ │ ├── project.properties
│ │ └── project.xml
│ └── src
│ ├── conf
│ │ └── MANIFEST.MF
│ └── java
│ └── pakt
│ ├── Salutation.java
│ └── SalutationLocal.java
├── SalutationApplication-war
│ ├── build
│ │ ├── empty
│ │ ├── generated-sources
│ │ │ └── ap-source-output
│ │ └── web
│ │ ├── index.html
│ │ ├── META-INF
│ │ │ └── MANIFEST.MF
│ │ └── WEB-INF
│ │ ├── classes
│ │ │ ├── pakt
│ │ │ └── servlet
│ │ │ └── SalutationServlet.class
│ │ └── web.xml
│ ├── build.xml
│ ├── dist
│ │ └── SalutationApplication-war.war
│ ├── nbproject
│ │ ├── ant-deploy.xml
│ │ ├── build-impl.xml
│ │ ├── genfiles.properties
│ │ ├── private
│ │ │ └── private.properties
│ │ ├── project.properties
│ │ └── project.xml
│ ├── src
│ │ ├── conf
│ │ │ └── MANIFEST.MF
│ │ └── java
│ │ ├── pakt
│ │ └── servlet
│ │ └── SalutationServlet.java
│ └── web
│ ├── index.html
│ └── WEB-INF
│ └── web.xml
└── src
└── conf
└── MANIFEST.MF
43 directories, 42 files
thufir@dur:~$
thufir@dur:~$ jar -tf NetBeansProjects/SalutationApplication/SalutationApplication-war/dist/SalutationApplication-war.war
META-INF/
META-INF/MANIFEST.MF
WEB-INF/
WEB-INF/classes/
WEB-INF/classes/pakt/
WEB-INF/classes/servlet/
WEB-INF/classes/servlet/SalutationServlet.class
WEB-INF/web.xml
index.html
thufir@dur:~$
thufir@dur:~$ jar -tf NetBeansProjects/SalutationApplication/SalutationApplication-ejb/dist/SalutationApplication-ejb.jar
META-INF/
META-INF/MANIFEST.MF
pakt/
pakt/Salutation.class
pakt/SalutationLocal.class
thufir@dur:~$
thufir@dur:~$
这就是应用程序的构建方式。
我是这样从scrach开始的:
NetBeansProjects/SalutationApp
├── build
│ ├── META-INF
│ │ └── MANIFEST.MF
│ ├── SalutationApp-ejb.jar
│ └── SalutationApp-war.war
├── build.xml
├── dist
│ └── gfdeploy
│ └── SalutationApp
│ ├── META-INF
│ │ └── MANIFEST.MF
│ ├── SalutationApp-ejb_jar
│ │ ├── ejb
│ │ │ └── Hello.class
│ │ └── META-INF
│ │ └── MANIFEST.MF
│ └── SalutationApp-war_war
│ ├── index.html
│ ├── META-INF
│ │ └── MANIFEST.MF
│ └── WEB-INF
│ ├── classes
│ │ └── srv
│ │ └── HelloServlet.class
│ └── web.xml
├── nbproject
│ ├── ant-deploy.xml
│ ├── build-impl.xml
│ ├── genfiles.properties
│ ├── private
│ │ └── private.properties
│ ├── project.properties
│ └── project.xml
├── SalutationApp-ejb
│ ├── build
│ │ ├── classes
│ │ │ ├── ejb
│ │ │ │ └── Hello.class
│ │ │ └── META-INF
│ │ │ └── MANIFEST.MF
│ │ ├── empty
│ │ └── generated-sources
│ │ └── ap-source-output
│ ├── build.xml
│ ├── dist
│ │ └── SalutationApp-ejb.jar
│ ├── nbproject
│ │ ├── ant-deploy.xml
│ │ ├── build-impl.xml
│ │ ├── genfiles.properties
│ │ ├── private
│ │ │ └── private.properties
│ │ ├── project.properties
│ │ └── project.xml
│ └── src
│ ├── conf
│ │ └── MANIFEST.MF
│ └── java
│ └── ejb
│ └── Hello.java
├── SalutationApp-war
│ ├── build
│ │ ├── empty
│ │ ├── generated-sources
│ │ │ └── ap-source-output
│ │ └── web
│ │ ├── index.html
│ │ ├── META-INF
│ │ │ └── MANIFEST.MF
│ │ └── WEB-INF
│ │ ├── classes
│ │ │ └── srv
│ │ │ └── HelloServlet.class
│ │ └── web.xml
│ ├── build.xml
│ ├── dist
│ │ └── SalutationApp-war.war
│ ├── nbproject
│ │ ├── ant-deploy.xml
│ │ ├── build-impl.xml
│ │ ├── genfiles.properties
│ │ ├── private
│ │ │ └── private.properties
│ │ ├── project.properties
│ │ └── project.xml
│ ├── src
│ │ ├── conf
│ │ │ └── MANIFEST.MF
│ │ └── java
│ │ └── srv
│ │ └── HelloServlet.java
│ └── web
│ ├── index.html
│ └── WEB-INF
│ └── web.xml
└── src
└── conf
└── MANIFEST.MF
52 directories, 46 files
我认为唯一的区别在于点击的顺序。我右键单击ejb和war项目的"clean",然后单击主应用程序,然后单击整个项目的"run"。
我觉得这就修复了包装。。。?
尽管.war文件看起来很相似,除了一些命名更改之外:
thufir@dur:~$
thufir@dur:~$ jar -tf NetBeansProjects/SalutationApp/SalutationApp-war/dist/SalutationApp-war.war
META-INF/
META-INF/MANIFEST.MF
WEB-INF/
WEB-INF/classes/
WEB-INF/classes/srv/
WEB-INF/classes/srv/HelloServlet.class
WEB-INF/web.xml
index.html
thufir@dur:~$
我不太确定为什么这个例子在其他例子没有运行的地方运行,除了可能错误地点击了不同子项目上的"clean"one_answers"run"之外。