• 一种获取OSGi任意Bundle的ClassLoader的方法


    在OSGi环境中,在Bundle内部代码中要得到自己Bundle的ClassLoader就很简单,在自己Bundle的代码中,直接写this.getClass().getClassLoader()就得到了自己Bundle的ClassLoader了。但怎么在其他Bundle或外部代码中得到任意一个Bundle的ClassLoader呢?Bundle和BundleContext都没有提供getClassLoader方法来获取,我就用了一种比较另类的方法来获取。突破口就在Bundle.loadClass(String className)方法,目前此方法已经在QuickWebFramework中应用了。

    思路:

    1.调用Bundle的findEntries方法,得到Bundle中任意一个class文件。

    2.根据这个class文件的路径,得到类名

    3.调用Bundle的loadClass方法,得到这个类

    4.调用这个类的getClassLoader方法,得到ClassLoader

     PS:

    1.由上面的思路可知此方法不能用于没有一个Java类的Bundle

    2.OSGi系统Bundle(即ID为0的Bundle)得不到class文件,所以此方法不能用于OSGi系统Bundle

    代码如下:

    import java.net.URL;
    import java.util.Enumeration;
    
    import org.osgi.framework.Bundle;
    
    /**
     * 插件辅助类
     * 作者博客:http://www.cnblogs.com/aaaSoft
     * @author aaa
     * 
     */
    public class BundleUtils {
        /**
         * 得到Bundle的类加载器
         * 
         * @param bundle
         * @return
         */
        public static ClassLoader getBundleClassLoader(Bundle bundle) {
            // 搜索Bundle中所有的class文件
            Enumeration<URL> classFileEntries = bundle.findEntries("/", "*.class",
                    true);
            if (classFileEntries == null || !classFileEntries.hasMoreElements()) {
                throw new RuntimeException(String.format("Bundle[%s]中没有一个Java类!",
                        bundle.getSymbolicName()));
            }
            // 得到其中的一个类文件的URL
            URL url = classFileEntries.nextElement();
            // 得到路径信息
            String bundleOneClassName = url.getPath();
            // 将"/"替换为".",得到类名称
            bundleOneClassName = bundleOneClassName.replace("/", ".").substring(0,
                    bundleOneClassName.lastIndexOf("."));
            // 如果类名以"."开头,则移除这个点
            while (bundleOneClassName.startsWith(".")) {
                bundleOneClassName = bundleOneClassName.substring(1);
            }
            Class<?> bundleOneClass = null;
            try {
                // 让Bundle加载这个类
                bundleOneClass = bundle.loadClass(bundleOneClassName);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }
            // 得到Bundle的ClassLoader
            return bundleOneClass.getClassLoader();
        }
    }
  • 相关阅读:
    【BZOJ3995】[SDOI2015]道路修建 线段树区间合并
    [Noip2016]天天爱跑步 LCA+DFS
    【BZOJ2870】最长道路tree 点分治+树状数组
    【BZOJ3730】震波 动态树分治+线段树
    【BZOJ2969】矩形粉刷 概率+容斥
    【BZOJ3029】守卫者的挑战 概率+背包
    【BZOJ3043】IncDec Sequence 乱搞
    【BZOJ3124】[Sdoi2013]直径 树形DP(不用结论)
    Django学习笔记之ORM多表操作
    SQL学习笔记之项目中常用的19条MySQL优化
  • 原文地址:https://www.cnblogs.com/aaaSoft/p/2883008.html
Copyright © 2020-2023  润新知