Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否有类似Tomcat的类加载器可以独立使用?_Java_Classpath_Osgi_Classloader_Encapsulation - Fatal编程技术网

Java 是否有类似Tomcat的类加载器可以独立使用?

Java 是否有类似Tomcat的类加载器可以独立使用?,java,classpath,osgi,classloader,encapsulation,Java,Classpath,Osgi,Classloader,Encapsulation,我正在使用一种Java类的应用服务器(Smartfox),它可以运行多个应用程序(“扩展”),但同时有一个非常不方便的类路径设置,以及尝试使用SLF4J时出现的问题 为了解决这个问题,我想将我的应用程序包装在它们自己的类加载器中。这样一个包含类加载器应该很像Tomcat,因为它 可以从包含JAR的目录加载类 优先选择来自其自身类路径的类,而不是来自父类路径的类 在我的项目中,是否有一个库有这样一个类加载器,我可以“拖放”它?如果不是的话,我自己创造它会很难吗?任何已知的陷阱?(和其他模块系统

我正在使用一种Java类的应用服务器(Smartfox),它可以运行多个应用程序(“扩展”),但同时有一个非常不方便的类路径设置,以及尝试使用SLF4J时出现的问题

为了解决这个问题,我想将我的应用程序包装在它们自己的类加载器中。这样一个包含类加载器应该很像Tomcat,因为它

  • 可以从包含JAR的目录加载类
  • 优先选择来自其自身类路径的类,而不是来自父类路径的类
在我的项目中,是否有一个库有这样一个类加载器,我可以“拖放”它?如果不是的话,我自己创造它会很难吗?任何已知的陷阱?

(和其他模块系统)都是专门设计来处理此类问题的

乍一看可能有些过分,但我认为您将很快重新实现OSGi alread为您所做的重要部分


例如,Eclipse使用的是OSGi实现。

因为我在嵌入OSGi容器时遇到了问题,而且确实有点过火,所以我推出了自己的解决方案。但总有一天我会学会使用OSGi,在这种情况下,我不需要嵌入框架

如果你碰巧想使用这段代码,它就在“用它做你想做的事”许可证下

公共类SmartfoxExtensionContainer扩展了AbstractExtension{
私有抽象扩展;
私有void initrealtextension(){
最终字符串区域=this.getOwnerZone();
System.out.println(“[SmartfoxExtensionContainer]=============区域的初始扩展”+区域+”======================”;
试一试{
//负载特性
File propFile=新文件(“wext/”+zone+“.properties”);
System.out.println(“[SmartfoxExtensionContainer]从”+propFile.getCanonicalPath()加载配置);
Properties props=新属性();
最终文件输入流ins=新文件输入流(propFile);
试一试{
道具加载(新的InputStreamReader(ins,“UTF-8”);
}最后{
试一试{
ins.close();
}捕获(IOE){}
}
//构造类加载器
File jarDir=新文件(props.getProperty(“classpath”,“wext/”+zone));
System.out.println(“[SmartfoxExtensionContainer]从”+jarDir.getCanonicalPath()加载类);
如果(!jarDir.isDirectory())抛出新的RuntimeException(“这不是现有目录”);
最终文件[]fs=jarDir.listFiles();
URL[]URL=新URL[fs.length];
对于(int f=0;f
这似乎正是我想要的,但尽管关于创建捆绑包的教程非常丰富,但我很难找到关于如何嵌入OSGI框架/容器(使用Equinox或Felix)的信息在我的应用程序中。有什么相关信息吗?@BartvanHeukelom:你通常不会在你的应用程序中嵌入OSGi,相反:你创建你的应用程序(和插件)作为OSGi捆绑包。我知道,但我的应用程序本身就是Smartfox中的插件/扩展,我不能将Smartfox放在OSGi中。无论如何,我在See上找到了一些关于扩展设置的详细信息。我写了一篇关于如何将OSGi嵌入应用程序的博文。对于最简单的情况,大约只有5行代码:
public class SmartfoxExtensionContainer extends AbstractExtension {

    private AbstractExtension extension;

    private void initRealExtension() {
        final String zone = this.getOwnerZone();
        System.out.println("[SmartfoxExtensionContainer] ========= Init extension for zone " + zone + " =========");

        try {

            // load properties
            File propFile = new File("wext/" + zone + ".properties");
            System.out.println("[SmartfoxExtensionContainer] Load config from " + propFile.getCanonicalPath());
            Properties props = new Properties();
            final FileInputStream ins = new FileInputStream(propFile);
            try {
                props.load(new InputStreamReader(ins, "UTF-8"));
            } finally {
                try {
                    ins.close();
                } catch (IOException e) {}
            }

            // construct classloader
            File jarDir = new File(props.getProperty("classpath", "wext/" + zone));
            System.out.println("[SmartfoxExtensionContainer] Load classes from " + jarDir.getCanonicalPath());
            if (!jarDir.isDirectory()) throw new RuntimeException("That is not an existing directory");

            final File[] fs = jarDir.listFiles();

            URL[] urls = new URL[fs.length];

            for (int f = 0; f < fs.length; f++) {
                System.out.println("[SmartfoxExtensionContainer]     " + fs[f].getName());
                urls[f] = fs[f].toURI().toURL();
            }

            SelfishClassLoader cl = new SelfishClassLoader(urls, SmartfoxExtensionContainer.class.getClassLoader());

            // get real extension class
            String mainClass = props.getProperty("mainClass", "Extension");
            System.out.println("[SmartfoxExtensionContainer] Main class: " + mainClass);

            @SuppressWarnings("unchecked")
            Class<? extends AbstractExtension> extClass = (Class<? extends AbstractExtension>) cl.loadClass(mainClass);

            // create extension and copy settings
            extension = extClass.newInstance();
            extension.setOwner(this.getOwnerZone(), this.getOwnerRoom());

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /* ======================= DELEGATES ======================= */

    @Override
    public void init() {
        initRealExtension();
        extension.init();
    }

    @Override
    public void destroy() {
        extension.destroy();
    }

    @Override
public void handleRequest(String arg0, ActionscriptObject arg1, User arg2, int arg3) {
    extension.handleRequest(arg0, arg1, arg2, arg3);
}

@Override
public void handleRequest(String arg0, String[] arg1, User arg2, int arg3) {
    extension.handleRequest(arg0, arg1, arg2, arg3);
}

@Override
public void handleInternalEvent(InternalEventObject arg0) {
    extension.handleInternalEvent(arg0);
}

@Override
public Object handleInternalRequest(Object params) {
    return extension.handleInternalRequest(params);
}

@Override
public void handleRequest(String cmd, JSONObject jso, User u, int fromRoom) {
    extension.handleRequest(cmd, jso, u, fromRoom);
}

    /* ======================= CUSTOM CLASSLOADER ======================= */

    private static class SelfishClassLoader extends URLClassLoader {

        SelfishClassLoader(URL[] urls, ClassLoader parent) {
            super(urls, parent);
        }

        // override default behaviour: find classes in local path first, then parent
        @Override protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {

            // First, check if the class has already been loaded
            Class<?> clz = findLoadedClass(name);

            if (clz == null) {

                try {
                    clz = findClass(name);
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from current class loader
                }

                if (clz == null) {
                    // If still not found, then invoke parent.findClass in order
                    // to find the class.
                    clz = getParent().loadClass(name);
                }

            }

            if (resolve) {
                resolveClass(clz);
            }

            return clz;

        };

    }

}