比赛是: TomEE 7.0 , openEjb 4.7.1 。我正在尝试创建实体Bean的实例, EJB实体2.1 BMP (Bean管理持久性)。
bean的部署工作正常,也是在客户端示例应用程序上创建远程home接口,但是当我尝试创建实体bean的istance时,会发生错误。
实体的代码是:
主页界面 BmpEntityHome.java
package it.enzo.ejb.entity.bmp;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
import javax.ejb.FinderException;
public interface BmpEntityHome extends EJBHome {
//Metodo Creazione
public BmpEntityBean createObject(String id) throws RemoteException, CreateException;
//Metodo finder
public BmpEntityBean findByPrimaryKey(String key) throws RemoteException, FinderException;
//Metodo di logica personalizzato
//public int getMetodoPersonalizzato() throws RemoteException;
}
远程接口 BmpEntityObject.java
package it.enzo.ejb.entity.bmp;
import java.rmi.RemoteException;
import javax.ejb.EJBObject;
public interface BmpEntityObject extends EJBObject{
public String getId() throws RemoteException;
public void setId(String id) throws RemoteException;
public String getValore1() throws RemoteException;
public void setValore1(String x) throws RemoteException;
public String getValore2() throws RemoteException;
public void setValore2(String x) throws RemoteException;
public int getAddizzione() throws RemoteException;
//Metodo di logica
//public void addizziona(int a, int b) throws RemoteException;
}
Bean接口 BmpEntityBean.java
package it.enzo.ejb.entity.bmp;
import java.rmi.RemoteException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.EntityBean;
import javax.ejb.EntityContext;
import javax.ejb.FinderException;
import javax.ejb.RemoveException;
public class BmpEntityBean implements EntityBean{
private static final long serialVersionUID = 1L;
private EntityContext ectx;
private String iD;
private String valore1;
private String valore2;
private int addizzione;
//Costruttore
public BmpEntityBean(){
System.out.println("BmbRntityBean chiamato il costruttore");
}
//Metodo di business
public void addizziona(int a, int b){
this.addizzione = a + b;
}
//Metodi getter e setter
public String getId() {
return iD;
}
public void setId(String iD) {
this.iD = iD;
}
public String getValore1() {
return valore1;
}
public void setValore1(String valore1) {
this.valore1 = valore1;
}
public String getValore2() {
return valore2;
}
public void setValore2(String valore2) {
this.valore2 = valore2;
}
public int getAddizzione() {
return addizzione;
}
//Metodo privato per creare la connessione al DB
private Connection getConnection(){
Connection cnn = null;
try {
Class.forName("org.sqlite.JDBC");
cnn = DriverManager.getConnection("jdbc:sqlite:EJBdatabase.db");
this.CreaTabelle(cnn);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return cnn;
}
private void CreaTabelle(Connection cnn){
Statement stat = null;
try {
stat = cnn.createStatement();
stat.executeUpdate("CREATE TABLE if not exists BmpEntityBeanTable (id string primary key, valore1 string, valore2 string, addizzione integer)");
stat.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
stat.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//Metodo finder
public String ejbFindByPrimaryKey(String key) throws FinderException{
PreparedStatement pstm = null;
Connection cnn = null;
try{
cnn = this.getConnection();
pstm = cnn.prepareStatement("SELECT id FROM BmpEntityBeanTable WHERE id = ?");
pstm.setString(1, key);
ResultSet rs = pstm.executeQuery();
if(rs.next())return key;
}catch(Exception e){e.printStackTrace();}
finally{
try {
pstm.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
cnn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
throw new FinderException("Entity con id "+key+" non Trovato");
}
//Metodo personalizzato sull'oggetto Home
//public int ejbHomeGetMetodoPersonalizzato(){
//return 2976;
//}
//Metodi di callback richiamati dal container
//Metodo di creazione
public BmpEntityBean ejbCreateObject(String id) throws CreateException{
Connection cnn = null;
PreparedStatement pstm = null;
this.iD = id;
try{
cnn = this.getConnection();
pstm = cnn.prepareStatement("INSERT INTO BmpEntityBeanTable (id) values ('"+id+"')");
pstm.execute();
return this;
}catch(Exception e){e.printStackTrace();}
finally{
try {
pstm.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
cnn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
throw new CreateException();
}
@Override
public void setEntityContext(EntityContext ctx) throws EJBException,
RemoteException {
// TODO Auto-generated method stub
this.ectx = ctx;
}
@Override
public void unsetEntityContext() throws EJBException, RemoteException {
// TODO Auto-generated method stub
this.ectx = null;
}
@Override
public void ejbRemove() throws RemoveException, EJBException,
RemoteException {
// TODO Auto-generated method stub
String key = (String) this.ectx.getPrimaryKey();
String id = key;
Connection cnn = null;
PreparedStatement pstm = null;
try{
cnn = this.getConnection();
pstm = cnn.prepareStatement("DELETE FROM BmpEntityBeanTable WHERE id = ?");
pstm.setString(1, id);
pstm.execute();
}catch(Exception e){e.printStackTrace();}
finally{
try {
pstm.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
cnn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public void ejbActivate() throws EJBException, RemoteException {
// TODO Auto-generated method stub
}
@Override
public void ejbPassivate() throws EJBException, RemoteException {
// TODO Auto-generated method stub
}
@Override
public void ejbLoad() throws EJBException, RemoteException {
// TODO Auto-generated method stub
String key = (String) this.ectx.getPrimaryKey();
String id = key;
Connection cnn = null;
PreparedStatement pstm = null;
try{
cnn = this.getConnection();
pstm = cnn.prepareStatement("SELECT * FROM BmpEntityBeanTable WHERE id = ?");
pstm.setString(1, id);
ResultSet rs = pstm.executeQuery();
if(rs.next()){
this.iD = id;
this.valore1 = rs.getString("valore1");
this.valore2 = rs.getString("valore2");
this.addizzione = rs.getInt("addizzione");
}
rs.close();
}catch(Exception e){e.printStackTrace();}
finally{
try {
pstm.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
cnn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public void ejbStore() throws EJBException, RemoteException {
// TODO Auto-generated method stub
String key = (String) this.ectx.getPrimaryKey();
String id = key;
Connection cnn = null;
PreparedStatement pstm = null;
try{
cnn = this.getConnection();
pstm = cnn.prepareStatement("UPDATE BmpEntityBeanTable set valore1 = ?, valore2 = ?, addizione = ? WHERE id = ?");
pstm.setString(1, this.valore1);
pstm.setString(2, this.valore2);
pstm.setInt(3, this.addizzione);
pstm.setString(4, id);
pstm.execute();
}catch(Exception e){e.printStackTrace();}
finally{
try {
pstm.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
cnn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
部署desciptor ejb-jar.xml
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd"
version="2.1">
<enterprise-beans>
<entity>
<ejb-name>BmpEntity</ejb-name>
<home>it.enzo.ejb.entity.bmp.BmpEntityHome</home>
<remote>it.enzo.ejb.entity.bmp.BmpEntityObject</remote>
<ejb-class>it.enzo.ejb.entity.bmp.BmpEntityBean</ejb-class>
<persistence-type>Bean</persistence-type>
<prim-key-class>java.lang.String</prim-key-class>
<reentrant>false</reentrant>
<primkey-field>iD</primkey-field>
</entity>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>BmpEntity</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
客户端示例应用
package it.enzo;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Properties;
import javax.ejb.CreateException;
import javax.ejb.EJB;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class ProvaServ
*/
@WebServlet("/ProvaServ")
public class ProvaServ extends HttpServlet {
private static final long serialVersionUID = 1L;
private it.enzo.ejb.entity.bmp.BmpEntityHome bmpEntityHome = null;
public ProvaServ() {
super();
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String comm = request.getParameter("comm");
if(comm!=null){
switch(comm.toString()){
case "bmpEntity_Start":
this.bmpEntityHome = null;
this.callBmpEntity();
break;
case "bmpEntity_Create":
if(this.bmpEntityHome!=null){
try {
String id = request.getParameter("id");
//it.enzo.ejb.entity.bmp.BmpEntityBean bmpEntityBean_TMP =
this.bmpEntityHome.createObject(id);
out.print("BmpEntity aggiunto: ");//+bmpEntityBean_TMP.getId());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
break;
}
}
out.print("<div><form action=''>"
+"<input type='hidden' name='comm' value='bmpEntity_Create'>"
+"Aggiungi un BmpEntity <input type='text' name='id' value='ID-DELL-ENTITY-1'>"
+"<input type='submit' value='Aggiungi'>"
+"</form></div>");
out.print("<br><br><a href='?comm=bmpEntity_Start'>Start BMPEntity</a><br>");
}
private void callBmpEntity(){
if(this.bmpEntityHome==null){
Properties p = new Properties();
p.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.RemoteInitialContextFactory");
p.put("java.naming.provider.url", "http://localhost:8080/tomee/ejb");
InitialContext initialContext;
Object object = null;
try {
initialContext = new InitialContext(p);
object = initialContext.lookup("BmpEntityRemoteHome");
this.bmpEntityHome = (it.enzo.ejb.entity.bmp.BmpEntityHome)
PortableRemoteObject.narrow(object, it.enzo.ejb.entity.bmp.BmpEntityHome.class);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
堆栈错误
nov 23, 2014 9:36:48 AM org.apache.openejb.core.transaction.EjbTransactionUtil handleSystemException
GRAVE: EjbTransactionUtil.handleSystemException: object is not an instance of declaring class
java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.openejb.core.entity.EntityContainer.createEJBObject(EntityContainer.java:340)
at org.apache.openejb.core.entity.EntityContainer.invoke(EntityContainer.java:182)
at org.apache.openejb.server.ejbd.EjbRequestHandler.doEjbHome_CREATE(EjbRequestHandler.java:420)
at org.apache.openejb.server.ejbd.EjbRequestHandler.processRequest(EjbRequestHandler.java:187)
at org.apache.openejb.server.ejbd.EjbDaemon.processEjbRequest(EjbDaemon.java:344)
at org.apache.openejb.server.ejbd.EjbDaemon.service(EjbDaemon.java:240)
at org.apache.openejb.server.ejbd.EjbServer.service(EjbServer.java:86)
at org.apache.openejb.server.httpd.ServerServlet.service(ServerServlet.java:58)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:44)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
java.rmi.RemoteException: The bean encountered a non-application exception; nested exception is:
java.lang.IllegalArgumentException: object is not an instance of declaring class
at org.apache.openejb.core.transaction.EjbTransactionUtil.handleSystemException(EjbTransactionUtil.java:155)
at org.apache.openejb.core.entity.EntityContainer.handleException(EntityContainer.java:484)
at org.apache.openejb.core.entity.EntityContainer.createEJBObject(EntityContainer.java:369)
at org.apache.openejb.core.entity.EntityContainer.invoke(EntityContainer.java:182)
at org.apache.openejb.server.ejbd.EjbRequestHandler.doEjbHome_CREATE(EjbRequestHandler.java:420)
at org.apache.openejb.server.ejbd.EjbRequestHandler.processRequest(EjbRequestHandler.java:187)
at org.apache.openejb.server.ejbd.EjbDaemon.processEjbRequest(EjbDaemon.java:344)
at org.apache.openejb.server.ejbd.EjbDaemon.service(EjbDaemon.java:240)
at org.apache.openejb.server.ejbd.EjbServer.service(EjbServer.java:86)
at org.apache.openejb.server.httpd.ServerServlet.service(ServerServlet.java:58)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:44)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.openejb.core.entity.EntityContainer.createEJBObject(EntityContainer.java:340)
... 25 more
包 openejb-core-4.7.1.jar
的类 EntityContainer.class 中的错误来源....
protected ProxyInfo createEJBObject(final Method callMethod, final Object[] args, final ThreadContext callContext, final InterfaceType type) throws OpenEJBException {
final BeanContext beanContext = callContext.getBeanContext();
callContext.setCurrentOperation(Operation.CREATE);
/*
* According to section 9.1.5.1 of the EJB 1.1 specification, the "ejbPostCreate(...)
* method executes in the same transaction context as the previous ejbCreate(...) method."
*
* For this reason the TransactionScopeHandler methods usally preformed by the invoke( )
* operation must be handled here along with the call explicitly.
* This ensures that the afterInvoke() is not processed between the ejbCreate and ejbPostCreate methods to
* ensure that the ejbPostCreate executes in the same transaction context of the ejbCreate.
* This would otherwise not be possible if container-managed transactions were used because
* the TransactionScopeManager would attempt to commit the transaction immediately after the ejbCreate
* and before the ejbPostCreate had a chance to execute. Once the ejbPostCreate method execute the
* super classes afterInvoke( ) method will be executed committing the transaction if its a CMT.
*/
final TransactionPolicy txPolicy = createTransactionPolicy(beanContext.getTransactionType(callMethod, type), callContext);
EntityBean bean = null;
Object primaryKey = null;
try {
// Get new ready instance
bean = instanceManager.obtainInstance(callContext);
// Obtain the proper ejbCreate() method
final Method ejbCreateMethod = beanContext.getMatchingBeanMethod(callMethod);
//HERE THE ERROR
// invoke the ejbCreate which returns the primary key
primaryKey = ejbCreateMethod.invoke(bean, args);//HERE THE ERROR
didCreateBean(callContext, bean);
// determine post create callback method
final Method ejbPostCreateMethod = beanContext.getMatchingPostCreateMethod(ejbCreateMethod);
// create a new context containing the pk for the post create call
final ThreadContext postCreateContext = new ThreadContext(beanContext, primaryKey);
postCreateContext.setCurrentOperation(Operation.POST_CREATE);
final ThreadContext oldContext = ThreadContext.enter(postCreateContext);
try {
// Invoke the ejbPostCreate method on the bean instance
ejbPostCreateMethod.invoke(bean, args);
// According to section 9.1.5.1 of the EJB 1.1 specification, the "ejbPostCreate(...)
// method executes in the same transaction context as the previous ejbCreate(...) method."
//
// The bean is first insterted using db.create( ) and then after ejbPostCreate( ) its
// updated using db.update(). This protocol allows for visablity of the bean after ejbCreate
// within the current trasnaction.
} finally {
ThreadContext.exit(oldContext);
}
// update pool
instanceManager.poolInstance(callContext, bean, primaryKey);
} catch (final Throwable e) {
handleException(txPolicy, e, callContext, bean);
} finally {
afterInvoke(txPolicy, callContext);
}
return new ProxyInfo(beanContext, primaryKey);
}
....
当我在客户端示例中尝试此操作时:
....
this.bmpEntityHome.createObject(id);
....
包 openejb-core-4.7.1.jar 的类EntityContainer.class 中的称为此方法:
...
protected ProxyInfo createEJBObject(final Method callMethod, final Object[]...
...
并在第340行指示:
...
// invoke the ejbCreate which returns the primary key
primaryKey = ejbCreateMethod.invoke(bean, args);
...
生成异常:
...
EjbTransactionUtil.handleSystemException: object is not an instance of declaring class
...
感谢!
答案 0 :(得分:1)
已解决...我错过了BmpEntityBean.class类(Business class)中的'ejbPostCreate'方法....