I have an OSGi application. Working with EJB context.lookup I had to set Thread context class loader as bundle class loader in order to be able to cast. Like this:
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
Entity entity=bean.getOne();
System.out.println(entity.getClass().getClassLoader());
output is
org.apache.felix.framework.BundleWiringImpl@7468776f
This code works. The problem that I can't cast if I have ArrayList
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
ArrayList<Entity> entities=bean.getMany();
This code returns ClassCastException.
Checking
ArrayList<Entity> temp=new ArrayList<Entity>();
System.out.println(temp.getClass().getClassLoader());
returns NULL - it means bootstrap class. How can it be fixed?
EDIT:
The most interesting, that ArrayList with String works, classic array works, but ArrayList and ArrayList with Entiry don't work.
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;
}
...
}
Here is the log
java.lang.ClassCastException: com.test.cmn.shd.base.dir.language.LanguageDirEntity cannot be cast to com.test.cmn.shd.base.dir.language.LanguageDirEntity at com.test.cmn.dt.base.Activator.start(Activator.java:83) at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:645) at org.apache.felix.framework.Felix.activateBundle(Felix.java:1977) at org.apache.felix.framework.Felix.startBundle(Felix.java:1895) at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:944) at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:931) at com.test.cmn.dt.loader.LoaderModel.startCoreModule(LoaderModel.java:149) at com.test.cmn.dt.loader.LoaderModel.access$100(LoaderModel.java:39) at 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.run(FutureTask.java:262) at javax.swing.SwingWorker.run(SwingWorker.java:335) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:744)
EDIT 2 - FULL CODE. This code is executed on client computer. JavaEE (GF4) is running on server. There are three osgi bundles:for server,for client and shared. The copy of shared is both on server and on clients and contains LanguageDirBeanRemote and 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);
}
EDIT 3 I opened a bug