使用ClassLoader指向不同路径的ServiceLoader [英] ServiceLoader using ClassLoader pointing to different path

查看:117
本文介绍了使用ClassLoader指向不同路径的ServiceLoader的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

几天以来一直在尝试此操作,但无法正常工作!

Have been trying this since few days and can't get it working!

我正在尝试构建一个可插入的Java应用程序,可以在其中从命令行运行它,并在单独的文件夹中提供插件(罐子).看来ServiceLoader可以满足我的要求,但是我认为我需要一个特殊的情况,即jar不是类路径的一部分,而它们存储在不同的位置,因此,我需要使用ClassLoder指向其网址到该文件系统路径.

I am trying to build a pluggable java application where I can run it from command line and provide plugins (jars) in a separated folder. It seems the ServiceLoader would fit my requirement but I think I need a special case where the jars are not part of the classpath whereas they are stored in a different location, and for this reason I would need to use a ClassLoder pointing its url to this file system path.

我要提供给主应用程序的一个插件是带有一些自定义功能的日志jar.

One of the plugin i want to provide to the main application is a log jar with some custom features.

下面是我正在使用的代码,但无法进入for/loop了.这意味着ServiceLoader无法识别/匹配任何类实现:

Here below the code I am using , but can't get to go into the for/loop .. it means that the ServiceLoader is not able to identify/match any class implementation :

final URL u = new File("C:\\data\\myLogJar-1.0-SNAPSHOT.jar").toURI().toURL();
ClassLoader ucl = new URLClassLoader(new URL[] {u});

ServiceLoader<Log> loader = ServiceLoader.load(Log.class, ucl);
for (Iterator<Log> iterator = loader.iterator(); iterator.hasNext(); ) {
    System.out.println(iterator.next());
}
loader = ServiceLoader.load(Log.class,ucl);
for (final Log log : loader) {
    log.info("Test log");                    
}

希望您能提供帮助! 非常感谢

I wish you could help! Thanks a lot

==== 添加项目文件:

==== adding project files :

主要可插拔应用程序:

    package com.company.dep.automation;

import com.company.dep.automation.pluggable.Log;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

import java.util.*;

public class Main {

    private static ServiceLoader<Log> serviceLoader;

    public static void main(String[] args) {

        final URL u;
        ClassLoader ucl = null;

        try {
            u = new File("C:\\data\\myLogJar-1.0-SNAPSHOT.jar").toURI().toURL();
             ucl = new URLClassLoader(new URL[]{u});
        } catch (MalformedURLException e1) {
            e1.printStackTrace();
        }

        ServiceLoader<Log> loader = ServiceLoader.load(Log.class, ucl);
        for (Iterator<Log> iterator = loader.iterator(); iterator.hasNext(); ) {
            System.out.println(iterator.next());
        }

        loader = ServiceLoader.load(Log.class, ucl);
        for (final Log log : loader) {
            log.info("Test log");
        }

    }

}

日志"插件

界面Log

package com.company.automation.service;

public interface Log {

    void trace(String message);
    void debug(String message);
    void info(String message);
    void warn(String message);
    void severe(String message);
    void error(String message);
    void fatal(String message);

}

其实现

package com.company.automation.service.impl;

import com.company.automation.service.Log;

public class LogImpl implements Log {

    @Override
    public void trace(String message) {
        log("TRACE --> " + message);
    }

    @Override
    public void debug(String message) {
        log("DEBUG --> " + message);
    }

    @Override
    public void info(String message) {
        log("INFO --> " + message);
    }

    @Override
    public void warn(String message) {
        log("WARN --> " + message);
    }

    @Override
    public void severe(String message) {
        log("SEVERE --> " + message);
    }

    @Override
    public void error(String message) {
        log("ERROR --> " + message);
    }

    @Override
    public void fatal(String message) {
        log("FATAL --> " + message);
    }

    private void log(String message) {
        System.out.println(message);
    }

}

  • 结构
  • =================

    =================

    按以下方式调整了项目结构,但仍然无效:

    Adjusted the project structure as following but still doesnt work :

    主应用程序:

    扩展程序:

    推荐答案

    它不起作用,因为它不是同一类Log,您的主要方法是在jar定义实现时尝试查找com.company.dep.automation.pluggable.Log的实现com.company.automation.service.Log的内容,这样ServiceLoader.load根本找不到任何东西.

    It doesn't work because it is not the same class Log, your main method try to find implementations of com.company.dep.automation.pluggable.Log while your jar defines an implementation of com.company.automation.service.Log such that ServiceLoader.load simply cannot find anything.

    您应该使用Main类将接口com.company.automation.service.Log从扩展jar移至项目,并在Main类中导入com.company.automation.service.Log而不是com.company.dep.automation.pluggable.Log,然后一切正常.

    You should move the interface com.company.automation.service.Log from the extension jar to the project with your Main class and import com.company.automation.service.Log instead of com.company.dep.automation.pluggable.Log in your Main class then everything should work.

    这篇关于使用ClassLoader指向不同路径的ServiceLoader的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆