2013-12-18 38 views
1

我试图用他的OSGi(Equinox)环境构建一个使用E4的桌面应用程序。对于我的用户安全即时通讯使用Shiro。但我可以从我的OSGi加载类,但shiro不能!如何在使用Shiro时在OSGI E4环境中加载Class?

在我的包我试试这个:

InitActivator.java:

public class InitActivator implements BundleActivator { 
private static BundleContext context; 

static BundleContext getContext() { 
    return context; 
} 

@Override 
public void start(BundleContext context) throws Exception { 

    //1. OSGi loadClass function 
    System.err.println(context.getBundle().loadClass("com.firm.demo.MyCustomClass") 
        .getName()); 
    //2. Using Apache Shiro ClassUtils 
    System.err.println("Shiro : " + ClassUtils.forName("com.firm.demo.MyCustomClass")); 

    } 

} 

的1 System.err的他限定名返回正确的类。 的2 System.err的返回org.apache.shiro.util.UnknownClassException:无法加载类命名为

如何使用四郎到OSGi的发现与类名?

回答

2

如果你看一下ClassUtils的来源,你会看到它是如何尝试加载类:http://grepcode.com/file/repo1.maven.org/maven2/org.apache.shiro/shiro-core/1.0.0-incubating/org/apache/shiro/util/ClassUtils.java#ClassUtils.forName%28java.lang.String%29

它尝试的第一件事是安装到线程的类加载器的帮助下加载类。如果失败,它会尝试加载加载ClassUtils的ClassLoader。如果失败,它会尝试使用系统ClassLoader加载该类。

你可以欺骗第一个线程上下文类加载器。我必须提到,这只是一个解决方法,而不是在OSGi世界中很好的解决方案:

BundleWiring bundleWiring = context.getBundle().adapt(BundleWiring.class); 
ClassLoader bundleClassLoader = bundleWiring.getClassLoader(); 
Thread currentThread = Thread.currentThread(); 

ClassLoader originalCl = currentThread.getContextClassLoader() 
currentThread.setContectClassLoader(bundleClassLoader); 
try { 
    System.err.println("Shiro : " + ClassUtils.forName("com.firm.demo.MyCustomClass")); 
} finally { 
    currentThread.setContextClassLoader(originalCl); 
} 
+1

+1请同时举报一个针对Shiro的错误。没有Classloader的情况下,库不应该按名称加载类,因为这在模块化环境中总是失败。 –

+0

真的很好!你在一周的研究后拯救我!非常感谢!你能报告四郎的错误吗?也许它打电话对修复它很有帮助。 – trouble

+0

*(由新成员发表没有足够的代表留下评论)* @TomNelson写道:我有一个类似的解决方法相同的问题,所以我报告https://issues.apache.org/jira/browse/SHIRO-537 – Leigh