В Maven Build я динамически генерирую некоторые типы Java, используя библиотеку генерации байтового кода (Byte Buddy). Естественно, эти файлы классов не имеют соответствующих исходных файлов. Таким образом будет создано только несколько классов. Большая часть кода для этого проекта будет источником Java. В идеале, источник Java будет ссылаться на сгенерированные типы статическим способом, а не на использование генерации кода отражения или времени выполнения, что означает, что классы должны находиться в пути класса компиляции для javac. Могу ли я получить сгенерированные классы в пути класса компиляции для одного и того же проекта Maven, т.е. Без отдельного проекта Maven и артефакта для хранения сгенерированного байтового кода, на который ссылается проект Maven, содержащий исходный код?
ОБНОВЛЕНИЕ: Я уже пробовал сгенерировать сгенерированные классы непосредственно в target/classes
i.e. project.build.outputDirectory
, в начале жизненного цикла сборки Maven, но, похоже, это не на пути к классу. Сгенерированные типы не могут быть разрешены с помощью Плагина компилятора Maven или IDE. Я также попытался использовать плагин Build Helper Maven, чтобы добавить дополнительный каталог ресурсов в target
, содержащий сгенерированные классы, которые затем автоматически копировались в target/classes
. Эта конфигурация показала ту же проблему.
ОБНОВЛЕНИЕ: Я создал полное публичное репо на GitHub: https://github.com/mches/so-42376851
Вот Maven POM для проекта. Я хочу иметь статические классы, которые ссылаются на расширенные классы байт кода:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>demo</groupId>
<artifactId>demo</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>demo-enhanced</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>demo</groupId>
<artifactId>demo-original</artifactId>
<version>${project.version}</version>
<overWrite>true</overWrite>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
<includes>**/*.class</includes>
<excludes>META-INF/</excludes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy-maven-plugin</artifactId>
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>transform</goal>
</goals>
<configuration>
<initialization>
<entryPoint>net.bytebuddy.test.SimpleEntryPoint</entryPoint>
<groupId>demo</groupId>
<artifactId>demo-transformer</artifactId>
</initialization>
<transformations>
<transformation>
<plugin>net.bytebuddy.test.SimplePlugin</plugin>
<groupId>demo</groupId>
<artifactId>demo-transformer</artifactId>
</transformation>
</transformations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
и вот родительский POM:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>demo</groupId>
<artifactId>demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>demo-original</module>
<module>demo-transformer</module>
<module>demo-enhanced</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<byte-buddy.version>1.6.9</byte-buddy.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>${byte-buddy.version}</version>
</dependency>
<dependency>
<groupId>demo</groupId>
<artifactId>demo-original</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>demo</groupId>
<artifactId>demo-transformer</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>demo</groupId>
<artifactId>demo-enhanced</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy-maven-plugin</artifactId>
<version>${byte-buddy.version}</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
foo/Bar.java(исходный источник):
package foo;
public class Bar {
}
net/bytebuddy/test/SimplePlugin.java(усилитель байтового кода):
package net.bytebuddy.test;
import net.bytebuddy.build.Plugin;
import net.bytebuddy.description.modifier.Visibility;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.FieldAccessor;
public class SimplePlugin implements Plugin {
@Override
public boolean matches(TypeDescription target) {
return target.getName().equals("foo.Bar");
}
@Override
public DynamicType.Builder<?> apply(DynamicType.Builder<?> builder, TypeDescription typeDescription) {
if (typeDescription.getTypeName().equals("foo.Bar")) {
builder = builder.defineField("qux", String.class, Visibility.PRIVATE)
.defineMethod("getQux", String.class, Visibility.PUBLIC)
.intercept(FieldAccessor.ofField("qux"))
.defineMethod("setQux", void.class, Visibility.PUBLIC)
.withParameter(String.class)
.intercept(FieldAccessor.ofField("qux"));
}
return builder;
}
}
foo/Baz.java(статический исходный файл, ссылающийся на динамический тип):
package foo;
public class Baz {
private Bar bar = new Bar();
public String getQuux() {
return bar.getQux();
}
public void setQuux(String quux) {
bar.setQux(quux);
}
}
UPDATE: Кажется, что Maven понимает структуру с объединенным модулем с расширенным байтовым кодом и исходным кодом статического класса, а также отдельными модулями для каждого, но IDE, IntelliJ и Eclipse не понимают путь класса для любой структуры, как это делает Maven.