如何在使用Shiro时在OSGI E4环境中加载Class?

时间:2013-12-18 08:35:20

标签: java osgi shiro e4

我正在尝试使用E4和他的OSGi(Equinox)环境构建桌面应用程序。对于我的用户安全即时通讯使用Shiro。但是我可以从我的OSGi加载课程,但是也不能!

在我的Bundle中我试试这个:

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:无法加载名为的类

如何使用Shiro进入OSGi查找带名字的类?

1 个答案:

答案 0 :(得分: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

它尝试的第一件事是在附加到线程的ClassLoader的帮助下加载类。如果失败,它会尝试使用加载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);
}