我学习Jboss部署EJB经常发生这样错误,最终搞定,把解决心得贡献给大家:
在这个错误上面一般都报一些实际错误,如果编译通过,则大多因为:
1.ejb-jar.xml写的有问题,比如缺项或者对应文件找不到。
2.ejb文件写得不规范,比如出现抽象类、缺乏ejb规定的方法。
Bean : TxBean
Method : public abstract Collection findByAccountId(Date, Date, String) throws FinderException
Section: 12.2.11
Warning: Each finder method must match one of the ejbFind<METHOD> methods define
d in the entity bean class.
这就是缺乏ejbFindByAccountId方法
10:01:28,250 WARN [verifier] EJB spec violation: Bean : CustomerBean Section: 12.2.2 Warning: The class must be defined as public and must not be abstract. 10:01:28,265 WARN [verifier] EJB spec violation: Bean : AccountBean Section: 12.2.2 Warning: The class must be defined as public and must not be abstract.
这个就是写了抽象类
上面是中间部署出现错误的求解,类代码如下
package examples.bmp;
import javax.ejb.*;
import java.rmi.*;
public interface Account extends EJBObject
{
// call ejb by this interface
public void deposit(double amt) throws RemoteException,AccountException;
public void withdraw(double amount) throws RemoteException,AccountException;
public double getBalance() throws RemoteException;
public String getOwnerName() throws RemoteException;
public void setOwnerName(String name) throws RemoteException;
public String getAccountID() throws RemoteException;
public void setAccountID(String id) throws RemoteException;
}
package examples.bmp;
import javax.ejb.*;
public interface AccountLocal extends EJBLocalObject
{
// call ejb by this interface
public void deposit(double amt) throws AccountException;
public void withdraw(double amount) throws AccountException;
public double getBalance();
public String getOwnerName();
public void setOwnerName(String name);
public String getAccountID();
public void setAccountID();
}
package examples.bmp;
import javax.ejb.*;
import java.rmi.*;
import java.util.*;
public interface AccountHome extends EJBHome
{
public Account create(String accountID,String ownerName) throws RemoteException,CreateException;
public Account findByPrimaryKey(AccountPK key) throws FinderException,RemoteException;
public Collection findByOwnerName(String name) throws FinderException,RemoteException;
public double getTotalBankValue() throws AccountException,RemoteException;
}
package examples.bmp;
import javax.ejb.*;
import java.rmi.*;
import java.util.*;
public interface AccountLocalHome extends EJBLocalHome
{
public Account create(String accountID,String ownerName) throws CreateException;
public Account findByPrimaryKey(AccountPK key) throws FinderException;
public Collection findByOwnerName(String name) throws FinderException;
public double getTotalBankValue() throws AccountException;
}
package examples.bmp;
public class AccountPK implements java.io.Serializable
{
public String accountID;
public AccountPK(String id)
{
this.accountID=id;
}
public AccountPK()
{
}
public String toString()
{
return this.accountID;
}
public boolean equals(Object o)
{
if(this==o)
return true;
if (!(o instanceof AccountPK))
{
return false;
}
return ((AccountPK)o).accountID.equals(this.accountID);
}
public int hashCode()
{
return accountID.hashCode();
}
}
package examples.bmp;
import java.sql.*;
import javax.naming.*;
import javax.ejb.*;
import java.util.*;
public class AccountBean implements EntityBean
{
protected EntityContext ctx;
/*
BMP的持久化域
accountID是主键域
*/
private String accountID;
private String ownerName;
private double balance;
public AccountBean()
{
System.out.println("New Bank Account Entity Bean java Object create By EJB Container");
}
/*
业务逻辑方法
1 向银行帐户存钱
2 从银行帐户取钱
*/
public void deposit(double amt) throws AccountException
{
System.out.println("deposit "+ amt +"called");
balance+=amt;
}
public void withdraw(double amount) throws AccountException
{
System.out.println("withdraw "+ amount +" called.");
if(amount>balance)
throw new AccountException("your balance is "+balance+" you can not withdraw"+amount);
balance-=amount;
}
/*
getter/setter方法,对应于持久化域
*/
public double getBalance()
{
System.out.println("getBalance called");
return this.balance;
}
public String getOwnerName()
{
System.out.println("getOwnerName called");
return this.ownerName;
}
public void setOwnerName(String name)
{
System.out.println("set owner name called");
this.ownerName=name;
}
public String getAccountID()
{
System.out.println("getAccountID called");
return this.accountID;
}
public void setAccountID(String id)
{
System.out.println("setAccountID called");
this.accountID=id;
}
/*
Home业务方法独立于任何帐号,它返回银行帐号的总和
*/
public double ejbHomeGetTotalBankValue() throws AccountException
{
PreparedStatement pstmt=null;
Connection conn=null;
ResultSet rs=null;
try
{
System.out.println("ejbHomeGetTotalBankValue called");
conn=getConnection();
pstmt=conn.prepareStatement("select sum(balance) as total from accounts");
rs=pstmt.executeQuery();
if(rs.next())
{
return rs.getDouble("total");
}
}
catch (Exception e)
{
}
finally
{
try
{
pstmt.close();
conn.close();
}
catch (Exception e)
{
}
}
throw new AccountException("ERROR");
}
//获得数据库连接
public Connection getConnection() throws Exception
{
try
{
Context ctx=new InitialContext();
javax.sql.DataSource ds= (javax.sql.DataSource)ctx.lookup("java:/SQLSERVER");
return ds.getConnection();
}
catch (Exception e)
{
return null;
}
}
/*
由容器调用,可以再其中获得所需资源
*/
public void ejbActivate()
{
System.out.println("ejbActivate called");
}
/*
在将实体bean从RDBMS删除前,EJB容器负责调用这一方法, 对应于客户调用home.remove
*/
public void ejbRemove() throws RemoveException
{
System.out.println("ejbRemove called");
AccountPK pk=(AccountPK)ctx.getPrimaryKey();
String id=pk.accountID;
PreparedStatement pstmt=null;
Connection conn=null;
try
{
conn=getConnection();
pstmt=conn.prepareStatement("delete from accounts where id=?");
pstmt.setString(1,id);
if(pstmt.executeUpdate()==0)
{
throw new RemoveException("account "+ pk+" failed to remove from database");
}
}
catch (Exception e)
{
}
}
/*
由容器调用,释放持有的资源,以便完成挂起操作
*/
public void ejbPassivate()
{
System.out.println("ejbPassivate called");
}
/*
由容器调用,更新bean实例,以反映存储在RDBMS中的最新值
*/
public void ejbLoad()
{
System.out.println("ejbLoad called");
AccountPK pk = (AccountPK)ctx.getPrimaryKey();
String id=pk.accountID;
PreparedStatement pstmt=null;
Connection conn=null;
ResultSet rs=null;
try
{
conn=getConnection();
pstmt=conn.prepareStatement("select ownerName,balance from accounts where id=?");
pstmt.setString(1,id);
rs=pstmt.executeQuery();
rs.next();
ownerName=rs.getString("ownerName");
balance=rs.getDouble("balance");
}
catch (Exception e)
{
e.printStackTrace();
}
}
/*
由容器调用,更新RDBMS数据,将内存中的实体bean数据更新到数据库中
*/
public void ejbStore()
{
System.out.println("ejbStore called");
PreparedStatement pstmt=null;
Connection conn=null;
try
{
conn=getConnection();
pstmt=conn.prepareStatement("update accounts set ownerName=?,balance=? where id=?");
pstmt.setString(1,ownerName);
pstmt.setDouble(2,balance);
pstmt.setString(3,accountID);
pstmt.executeUpdate();
}
catch (Exception e)
{
}
}
/*
有容器调用,将特定上下文关联到这一EJB实例,一旦设置好,便可以通过它查询到环境信息
*/
public void setEntityContext(EntityContext ctx)
{
System.out.println("setEntityContext called");
this.ctx=ctx;
}
/*
由容器调用,将特定上下文销毁
*/
public void unsetEntityContext()
{
System.out.println("unsetEntityContext called");
this.ctx=null;
}
public void ejbPostCreate(String accountID,String ownerName)
{
}
/*
对应于home接口中的create 当客户调用home接口中的create方法,home对象
会调用ejbCreate方法
*/
public AccountPK ejbCreate(String accountID,String ownerName) throws CreateException
{
PreparedStatement pstmt=null;
Connection conn=null;
try
{
System.out.println("ejbCreate called");
this.accountID= accountID;
this.ownerName=ownerName;
this.balance=0;
conn=getConnection();
pstmt=conn.prepareStatement("insert into accounts(id,ownerName,balance) values(?,?,?)");
pstmt.setString(1,accountID);
pstmt.setString(2,ownerName);
pstmt.setDouble(3,balance);
pstmt.executeUpdate();
return new AccountPK(accountID);
}
catch (Exception e)
{
return null;
}
}
/*
通过主键查找Account
*/
public AccountPK ejbFindByPrimaryKey(AccountPK key) throws FinderException
{
PreparedStatement pstmt=null;
Connection conn=null;
try
{
System.out.println("ejbFindByPrimaryKey called");
conn=getConnection();
pstmt=conn.prepareStatement("select id from accounts where id=?");
pstmt.setString(1,key.toString());
ResultSet rs=pstmt.executeQuery();
rs.next();
return key;
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
}
/*
通过持有人查找account
*/
public Collection ejbFindByOwnerName(String name) throws FinderException
{
PreparedStatement pstmt=null;
Connection conn=null;
Vector v=new Vector();
try
{
System.out.println("ejbFindByOwnerName called");
conn=getConnection();
pstmt=conn.prepareStatement("select id from accounts where ownerName=?");
pstmt.setString(1,name);
ResultSet rs=pstmt.executeQuery();
while(rs.next())
{
String id=rs.getString("id");
v.addElement(new AccountPK(id));
}
return v;
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
}
}
package examples.bmp;
public class AccountException extends Exception
{
public AccountException()
{
super();
}
public AccountException(Exception e)
{
super(e.toString());
}
public AccountException(String e)
{
super(e);
}
}
package examples.bmp;
import javax.ejb.*;
import javax.naming.*;
import java.rmi.*;
import javax.rmi.*;
import java.util.*;
public class AccountClient
{
public static void main(String[] args) throws Exception
{
Account account=null;
try
{
Properties props=new Properties();
props.setProperty("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
props.setProperty("java.naming.provider.url","jnp://192.168.52.136:1099");
Context ctx=new InitialContext(props);
Object obj=ctx.lookup("AccountEJB");
AccountHome home=(AccountHome)PortableRemoteObject.narrow(obj,AccountHome.class);
System.err.println("Total of all accounts in bak initially="+home.getTotalBankValue());
home.create("123-456-7890","John Smith");
Iterator it=home.findByOwnerName("John Smith").iterator();
if(it.hasNext())
{
account=(Account)javax.rmi.PortableRemoteObject.narrow(it.next(),Account.class);
}
else
{
throw new Exception("could not find account");
}
System.out.println("Initial Balance="+account.getBalance());
account.deposit(100);
System.out.println("After depositing 100, amount balance ="+account.getBalance());
System.out.println("Total of all accounts in bank now "+home.getTotalBankValue());
AccountPK pk = (AccountPK)account.getPrimaryKey();
account=null;
account=home.findByPrimaryKey(pk);
System.out.println("Found account with ID"+pk+", balance="+account.getBalance());
System.out.println("now trying to withdraw 150 ,which is more than is currently avaliable ");
account.withdraw(150);
}
catch (Exception e)
{
}
}
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar>
<enterprise-beans>
<entity>
<ejb-name>AccountEJB</ejb-name>
<home>examples.bmp.AccountHome</home>
<remote>examples.bmp.Account</remote>
<ejb-class>examples.bmp.AccountBean</ejb-class>
<persistence-type>Bean</persistence-type>
<prim-key-class>examples.bmp.AccountPK</prim-key-class>
<reentrant>false</reentrant>
</entity>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>AccountEJB</ejb-name>
<method-intf>Remote</method-intf>
<method-name>*</method-name>
</method>
<method>
<ejb-name>AccountEJB</ejb-name>
<method-intf>Local</method-intf>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
<?xml version="1.0" encoding="UTF-8"?>
<datasources>
<local-tx-datasource>
<!--
<jndi-name>MySql</jndi-name>
<connection-url>jdbc:mysql://192.168.52.136:3306/test</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>root</user-name>
<password></password>
</local-tx-datasource>
-->
<jndi-name>SQLSERVER</jndi-name>
<connection-url>jdbc:sqlserver://127.0.0.1:1433;DatabaseName=test</connection-url>
<driver-class>com.microsoft.sqlserver.jdbc.SQLServerDriver</driver-class>
<user-name>sa</user-name>
<password>Cp123456</password>
</local-tx-datasource>
</datasources>
注意把上面的jndi配置拷到jboss下面的deploy下面,jdbc驱动拷到lib下面,运行客户端,ok