У меня нет проблем под Windows. Компиляция javax прекрасно работает с предоставленной здесь информацией, но вызов ее из сборки докера с использованием gradle приводит к ошибкам пути к классам: не найден пакет, который существует под указанным путем к классам.
Настройка моего проекта выглядит следующим образом:
У меня есть общий код, который генерируется до всего остального, после этого генерируется проект генератора кода. Для каждого подмодуля я генерирую jar-файл, который можно прочитать для генерации кода, и вызываю генератор из gradle, чтобы сгенерировать клиентский jar для моего REST API.
Во-первых, все классы полезной нагрузки создаются и хранятся в пакете «project.payload», где находятся файлы .class. Этот сборник проходит через отлично.
После этого я генерирую клиентов из своего REST API, где обычно всегда импортирую пакет «project.payload». Из-за того, что некоторые классы используются всегда, я тоже их импортирую. Так что моя сгенерированная структура класса выглядит как
package project;
import default_project.AutoGenerated;
...
import project.payload; // This is where the compiler fails due to "package not found"
...
public class Client...
Это означает, что он не может найти только сгенерированные классы.
Выходной каталог генератора выглядит следующим образом:
temp\
|--- project\
|--- Client.java
|--- payload\
|--- Payload1.java
|--- Payload1.class
...
Каталог не пустой. Каталог, добавленный в classpath, является папкой temp
, что означает правильную иерархию пакетов.
Я попытался добавить каждый класс вручную в classpath, установив для свойства java.ext.dirs
абсолютный путь к временной папке и добавив временную папку абсолютно с подстановочным знаком (путь /*).
Мне бы не хотелось упаковывать классы полезной нагрузки в файл jar и добавлять файл jar в путь к классам, хотя это, вероятно, сработало бы.
Итак, вот метод, который генерирует файлы .class
из ранее сгенерированного действительного исходного кода:
protected void compileClass(File targetFile, String source)
{
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
String localClasspath = new File("temp").getAbsolutePath();
List<String> optionsList = new ArrayList<>();
optionsList.add("-classpath");
optionsList.add(System.getProperty("java.class.path") + ";" + localClasspath);
Iterable<? extends JavaFileObject> compilationUnit = fileManager.getJavaFileObjectsFromFiles(Arrays.asList(targetFile));
JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnostics, optionsList, null, compilationUnit);
if (task.call())
{
LOGGER.info("Compilation run through successfully!");
}
else
{
for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics())
LOGGER.severe(String.format("Error on line %d in %s%n: %s", diagnostic.getLineNumber(), diagnostic.getSource().toUri(), diagnostic.getMessage(null)));
LOGGER.info(() -> "Source code: " + source);
ClientGenerator.errorExitProgram();
}
}
В конце концов, я ожидаю, что один и тот же код, выполняемый в двух разных операционных системах, будет вести себя одинаково, поэтому я очень сомневаюсь, что это предполагаемое поведение, но все же должны быть решения, как исправить поведение на Обе системы / лучше обходят поведение, не упаковывая сгенерированные классы в файлы JAR.