gpt4 book ai didi

java - ServiceLoader使用ClassLoader指向不同的路径

转载 作者:行者123 更新时间:2023-11-30 02:45:39 25 4
gpt4 key购买 nike

几天来我一直在尝试这个方法,但无法正常工作!

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

我想向主应用程序提供的插件之一是具有一些自定义功能的日志 jar。

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

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");
}

希望能帮到你!非常感谢

====添加项目文件:

主要可插拔应用程序:

enter image description here

    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");
}

}

}

“日志”插件

界面日志

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);
}

}
  • 结构

enter image description here

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

将项目结构调整如下,但仍然不起作用:

主要应用程序: enter image description here

扩展应用程序: enter image description here

最佳答案

它不起作用,因为它不是同一个类Log,您的主要方法尝试查找com.company.dep.automation.pluggable.Log的实现而您的 jar 定义了 com.company.automation.service.Log 的实现,使得 ServiceLoader.load 根本找不到任何内容。

您应该将接口(interface)com.company.automation.service.Log从扩展jar移动到带有Main类的项目并导入com.company在您的 Main 类中使用 .automation.service.Log 而不是 com.company.dep.automation.pluggable.Log ,那么一切都应该正常。

关于java - ServiceLoader使用ClassLoader指向不同的路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40284401/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com