我已经搜索了几天来为我的,在我看来不是太难但显然无法解决的问题找到一些解决方案。
我有一个包含一些 EJB 的 EAR 项目,一个 Web 客户端(工作正常),现在我添加了一个应用程序客户端模块。
由于一切都在同一个项目中,我认为在应用程序客户端的主类中进行简单的@EJB 注入就可以了。我还尝试了 JNDI 查找。我使用 eclipse 和 glassfish 作为服务器并尝试运行应用程序 1. 在 eclipse 中(我注入的 bean 只是空)和 2. 从 glassfish 管理下载客户端存根并尝试使用 sh appclient -client 启动它(或-jar)OmazanClient.jar(以及隐藏在client-stub文件夹中的另外两个jar)。在那里,我主要得到一个“ClassNotFoundExeption:Main”,例如
java.lang.ClassNotFoundException: Main
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at org.glassfish.appclient.client.acc.ACCClassLoader.findClass(ACCClassLoader.java:212)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at org.glassfish.appclient.client.acc.FacadeLaunchable.getMainClass(FacadeLaunchable.java:262)
at org.glassfish.appclient.client.acc.AppClientContainer.setClient(AppClientContainer.java:324)
at org.glassfish.appclient.client.acc.AppClientContainerBuilder.createContainer(AppClientContainerBuilder.java:185)
at org.glassfish.appclient.client.acc.AppClientContainerBuilder.newContainer(AppClientContainerBuilder.java:172)
at org.glassfish.appclient.client.AppClientFacade.createContainerForAppClientArchiveOrDir(AppClientFacade.java:492)
at org.glassfish.appclient.client.AppClientFacade.createContainer(AppClientFacade.java:454)
at org.glassfish.appclient.client.AppClientFacade.prepareACC(AppClientFacade.java:269)
at org.glassfish.appclient.client.acc.agent.AppClientContainerAgent.premain(AppClientContainerAgent.java:82)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:323)
at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:338)
因此,对于注入,我的代码如下所示:
public class Main {
@EJB (mappedName="ejb/customerBean")
public static CustomerInterface customerBean;
@EJB (mappedName="ejb/productBean")
public static ProductInterface productBean;
public static void main(String[] args) {
try{
Main m = new Main();
m.runDialog();
}
catch (Exception e){
e.printStackTrace();
}
}
/* (non-Java-doc)
* @see java.lang.Object#Object()
*/
public Main() {
super();
}
private void runDialog() throws Exception{
System.out.println("Test");
List<ProductDTO> productList = productBean.getAllProducts();
...
我的远程界面如下所示:
@Remote
public interface ProductInterface {
public int addProduct(String productName);
public void deleteProduct(int prodid);
public void updateProduct(int prodid, String newName);
List<ProductDTO> getAllProducts();
...
我的实现是这样的:
/**
* Session Bean implementation productInterface
* */
@Stateless(mappedName="ejb/productBean")
@LocalBean
@WebService
public class ProductBean implements ProductInterface {
@EJB ProductEAO eao;
@EJB Conversion conv;
/**
* Default constructor.
*/
public ProductBean() {
// TODO Auto-generated constructor stub
}
@Override
public int addProduct(String prodName) {
return eao.addProduct(prodName);
}
@Override
public List<ProductDTO> getAllProducts() {
List<ProductDTO> result = new ArrayList<ProductDTO>();
List<Product> allProducts = eao.allProducts();
for (Product pr : allProducts) {
ProductDTO ci = conv.fromProduct(pr);
result.add(ci);
}
return result;
}
... 以此类推(接口需要的所有方法都实现了,这里尽量缩短)
而 MANIFEST.MF 只是
Manifest-Version: 1.0
Main-Class: Main
我已经尝试了很多类似 JNDI 查找,给出 bean 名称(参见示例)等。但是要么找不到接口(查找),要么 bean 简单地为空。
但是我也不太确定如何运行应用程序客户端。我认为 glassfishs appclient 是正确的起点?它应该是一个控制台交互,所以没有摆动组件或类似的东西。
现在,我会感谢我可能错过的任何建议。
干杯:)
找到了解决方案。不知何故,JNDI 现在可以工作了。另一个问题是我的数据库查询返回了一个对象而不是原始值或字符串——这导致了缓冲区错误。
但是,我仍然对如何正确导出运行应用程序客户端感到困惑。也许有人有想法?!