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

类加载器不同导致类型强制转换报错:java.lang.ClassCastException

springboot中SPI机制