Как я могу изменить загрузчик классов getSystemJavaCompiler - PullRequest
0 голосов
/ 21 сентября 2018

Я динамически компилирую исходники Java, используя API компилятора Java.Мои сгенерированные исходные файлы наследуются от com.example.BaseClass, который является обычным классом, а не генерируется динамически.Сгенерированные исходные коды Java выглядят так:

public class Foo implements com.example.BaseClass
{
    @Override
    public Integer getAnswer(com.example.Context context) throws Exception
    {
        return ...;
    }
}

Все отлично работает при работе в IDE, но после упаковки в банку Springboot мой com.example.BaseClass перемещается в BOOT-INF / classes / com.example.BaseClass.При динамической компиляции я теперь получаю:

/Foo.java:1: error: package com.example does not exist 
public class Foo implements com.example.BaseClass
                                       ^

Я пытаюсь изменить загрузчик классов компилятора, чтобы компилятор осуществлял поиск в BOOT-INF / classes.

    ClassLoader before = Thread.currentThread().getContextClassLoader();
    Thread.currentThread().setContextClassLoader(new CustomClassloader(before));
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    Thread.currentThread().setContextClassLoader(before);

Однако отладкапоказывает, что мой метод CustomClassloader.loadClass (имя строки) никогда не вызывается.Дополнительная отладка показала, что compiler.getClass (). GetClassloader () возвращает

java.net.FactoryURLClassLoader@39a5ae48

Итак, CustomClassloader не используется экземпляром Compiler.Как я могу заставить компилятор использовать мой CustomClassloader?Лучшие решения для решения проблемы компиляции также приветствуются: -).

1 Ответ

0 голосов
/ 22 сентября 2018

Существуют некоторые странности в том, как стандартный компилятор Java выполняет поиск, и он не всегда корректно разрешает выход из пути запущенного класса.В любом случае, он выполняет это разрешение, используя вызов JavaFileManager.list .

Он вызовет его как минимум 4 раза в процессе поиска вашего базового класса.Переопределите ForwardingJavaFileManager и передайте его в getTask , чтобы он нашел ресурс и возвратил его.

В качестве альтернативы, вы можете использовать компилятор Janino in-momeory. библиотека, которая устанавливает подделку в файловой системе памяти (без компиляции на диск) и все еще использует компилятор plaform и разбирает всю эту чушь пути к классам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...