java类加载器不同导致SPI 报错 not a subtype
Posted master-dragon
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java类加载器不同导致SPI 报错 not a subtype相关的知识,希望对你有一定的参考价值。
如下图
整段代码如下,当注释掉myThread.setContextClassLoader(myClassLoader);
后才正常运行
package com.hotload;
import java.util.ServiceLoader;
class MyThread extends Thread{
@Override
public void run() {
try{
ServiceLoader<A> serviceLoader = ServiceLoader.load(A.class);
A a = serviceLoader.iterator().next();
a.say();
} catch (Exception e){
}
}
}
/**
* @Author mubi
* @Date 2021/9/25 15:29
*/
public class Application {
public static void main(String[] args) throws Exception {
String rootPath = "/Users/mubi/git_workspace/java8/java8-api/src/main/java";
MyComOtherClassLoader myClassLoader = new MyComOtherClassLoader();
myClassLoader.path = rootPath;
MyThread myThread = new MyThread();
myThread.setContextClassLoader(myClassLoader);
myThread.start();
}
}
要知道错误,首先要理解java spi,serviceload是用线程上线文加载器的,我们debug到报错代码:接口A的类加载器和接口A的实现类Aimp1的类加载器是不同的,因为设置了线程上线文:
当代码改成如下后正常运行
package com.hotload;
import java.lang.reflect.Method;
import java.util.ServiceLoader;
class MyThread extends Thread{
@Override
public void run() {
try {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class clazzA = cl.loadClass("com.hotload.A");
ServiceLoader<A> serviceLoader = ServiceLoader.load(clazzA);
Object aimp1 = serviceLoader.iterator().next();
Method method = aimp1.getClass().getMethod("say");
method.invoke(aimp1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* @Author mubi
* @Date 2021/9/25 15:29
*/
public class Application {
public static void main(String[] args) throws Exception {
String rootPath = "/Users/mubi/git_workspace/java8/java8-api/src/main/java";
MyComOtherClassLoader myClassLoader = new MyComOtherClassLoader();
myClassLoader.path = rootPath;
MyThread myThread = new MyThread();
myThread.setContextClassLoader(myClassLoader);
myThread.start();
}
}
debug 查看如下(java.util.ServiceLoade
的 375行 可以走完,不再fail了)
以上是关于java类加载器不同导致SPI 报错 not a subtype的主要内容,如果未能解决你的问题,请参考以下文章
java类加载器不同导致SPI 报错 not a subtype
java类加载器不同导致SPI 报错 not a subtype
类加载器不同导致类型强制转换报错:java.lang.ClassCastException
类加载器不同导致类型强制转换报错:java.lang.ClassCastException