当前位置: 首页 > 面试题库 >

OSGi客户端中的RMI ClassCastException从JavaEE服务器访问EJB

单于轶
2023-03-14
问题内容

我有一个OSGi应用程序。使用EJB context.lookup,我必须将Thread上下文类加载器设置为bundle类加载器,以便进行转换。像这样:

Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
Entity entity=bean.getOne();
System.out.println(entity.getClass().getClassLoader());

输出是

org.apache.felix.framework.BundleWiringImpl@7468776f

此代码有效。如果我有ArrayList我无法转换的问题

Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
ArrayList<Entity> entities=bean.getMany();

此代码返回ClassCastException。

检查

ArrayList<Entity> temp=new ArrayList<Entity>();
System.out.println(temp.getClass().getClassLoader());

返回NULL-这意味着引导类。如何解决?

编辑:

最有趣的是,使用String的ArrayList有效,经典的数组有效,但是使用Entiry的ArrayList和ArrayList不起作用。

Class Bean {
....
  @Override //THIS DOESN'T WORK
    public ArrayList<Entity> readMany() {
        Entity dir1=new Entity();
        dir1.setContent("1 test");
        Entity dir2=new Entity();
        dir2.setContent("2 test");
        ArrayList<Entity> result=new ArrayList<>();
        result.add(dir1);result.add(dir2);
        return result;
    }

    @Override //THIS WORKS
    public ArrayList<String> readMany2() {
        String str1=new String("1 test");
        String str2=new String("2 test");
        ArrayList<String> result=new ArrayList<>();
        result.add(str1);
        result.add(str2);
        return result; 
    }

@Override //THIS WORKS
public Entity[] readArray() {
    ArrayList<Entity> al=readMany();
    Entity[] ar=new Entity[al.size()];
    for (int i = 0; i < al.size(); i++) {
        ar[i]=al.get(i);
    }
    return ar;
}

@Override //THIS DOESN'T WORK
public ArrayList readSimpleArrayList() {
    ArrayList<Entity> gal=readMany();
    ArrayList al= new ArrayList();
    for (Entity obj : gal) {
        al.add(obj);
    }
    return al;
}
...
}

这是日志

java.lang.ClassCastException:com.test.cmn.shd.base.dir.language.LanguageDirEntity无法转换为com.test.cmn.dt.base的com.test.cmn.shd.base.dir.language.LanguageDirEntity
org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:645)上的.Activator.start(Activator.java:83)org.apache.felix.framework.Felix.activateBundle(Felix.java:1977)
)在org.apache.felix.framework.Felix.startBundle(Felix.java:1895)在org.apache.felix.framework.BundleImpl.start(BundleImpl.java:944)在org.apache.felix.framework.BundleImpl。从com.test.cmn.dt.loader.LoaderModel.startCoreModule(LoaderModel.java:149)开始(BundleImpl.java:931)在com.test.cmn.dt.loader.LoaderModel.access
$ 100(LoaderModel.java:39) )com.test.cmn.dt.loader.LoaderModel $
InstallAndStartModuleWorker.doInBackground(LoaderModel.java:79)at
com.test.cmn.dt.loader.LoaderModel $
InstallAndStartModuleWorker.doInBackground(LoaderModel.java:73)at
javax.swing.SwingWorker $ 1.call(SwingWorker.java:296)at
java.util.concurrent.FutureTask。在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)在javax.swing.SwingWorker.run(SwingWorker.java:335)运行(FutureTask.java:262)在java.util.concurrent.ThreadPoolExecutor
$
Worker运行.run(ThreadPoolExecutor.java:615)在java.lang.Thread.run(Thread.java:744)java.util.concurrent.ThreadPoolExecutor
$
Worker.run(ThreadPoolExecutor.java:615)处的runWorker(ThreadPoolExecutor.java:1145)在java.lang.Thread.run(Thread.java:744)处java.util.concurrent.ThreadPoolExecutor
$
Worker.run(ThreadPoolExecutor.java:615)处的runWorker(ThreadPoolExecutor.java:1145)在java.lang.Thread.run(Thread.java:744)处

编辑2-完整代码。
此代码在客户端计算机上执行。JavaEE(GF4)正在服务器上运行。osgi包分为三个:服务器,客户端和共享。共享的副本在服务器和客户端上都包含,并且包含LanguageDirBeanRemote和LanguageDirEntity。

ClassLoader thatLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
try {
       Properties jndiProps = new Properties();
       jndiProps.put("java.naming.factory.initial", "com.sun.enterprise.naming.impl.SerialInitContextFactory");
       jndiProps.put("java.naming.factory.url.pkgs", "com.sun.enterprise.naming");
       jndiProps.put("java.naming.factory.state", "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");
       jndiProps.setProperty("org.omg.CORBA.ORBInitialHost", "x.x.x.x");
       jndiProps.setProperty("org.omg.CORBA.ORBInitialPort", "3700");
       InitialContext ctx = new InitialContext(jndiProps);
       LanguageDirBeanRemote bean=(LanguageDirBeanRemote)ctx.lookup("java:global/...");
       ArrayList<LanguageDirEntity> elements=bean.readDirectory();
      System.out.println("HERE I GET THE ERROR:"+elements.get(0).getContent());
} finally {
Thread.currentThread().setContextClassLoader(thatLoader);
}

编辑3 我打开了一个错误


问题答案:

谢谢大家。我终于解决了。我正在写我所了解的方式。将gf-client与osgi client一起使用的方法有两种:

  1. 非官方方式-取用玻璃鱼捆并通过osgi api手动安装。
  2. 官方方式-将glassfish / lib / gf-client.jar和glassfish / modules复制到客户端,并在classpath中添加gf-clinet.jar。

我不知道我是怎么做的。我不能说错,因为玻璃鱼本身就是osgi。当我用第二种方法做时,这个问题消失了。因此,当您从java classpath和osgibundle加载时,问题出在不同的类加载器中。



 类似资料:
  • 我是NodeJS的新手。假设我有一个用Golang的websocket包实现的echo服务器: nodejs客户机代码应该是什么样子?

  • 24.10 在客户端访问RESTful服务 RestTemplate是客户端访问RESTful服务的核心类。它在概念上类似于Spring中的其他模板类,例如JdbcTemplate、 JmsTemplate和其他Spring组合项目中发现的其他模板类。 RestTemplate’s behavior is customized by providing callback methods and c

  • 我想在一些计算机之间建立点对点连接,这样用户就可以在没有外部服务器的情况下聊天和交换文件。我最初的想法如下: 我在服务器上制作了一个中央服务器插座,所有应用程序都可以连接到该插座。此ServerSocket跟踪已连接的套接字(客户端),并将新连接的客户端的IP和端口提供给所有其他客户端。每个客户端都会创建一个新的ServerSocket,所有客户端都可以连接到它。 换句话说:每个客户端都有一个Se

  • 我在Infinispan上使用Memcached创建了一个分布式集群。 现在,我需要使用SpyMemcach客户端访问我的缓存。 我试过这个: 但是我得到了这个错误: 在我看来,这已经有点令人困惑了。如果通过一台机器我有多个缓存,我的客户会选择哪个缓存??? 非常感谢!

  • 本文向大家介绍java通过客户端访问服务器webservice的方法,包括了java通过客户端访问服务器webservice的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了java通过客户端访问服务器webservice的方法。分享给大家供大家参考,具体如下: 更多关于java相关内容感兴趣的读者可查看本站专题:《Java数据结构与算法教程》、《Java文件与目录操作技巧汇总》、《J

  • 我想知道如何使用混合流刷新IdentityServer4客户端中的访问令牌,它是使用ASP构建的。NET核心MVC。 如果我正确理解了整个概念,客户端首先需要拥有“离线访问”范围,以便能够使用刷新令牌,这是启用短期访问令牌的最佳实践,并且能够撤销刷新令牌,防止向客户端颁发任何新的访问令牌。 我成功地获得了一个访问令牌和一个刷新令牌,但是我应该如何处理MVC客户端中访问令牌的实际更新过程呢? Ope