В Maven Build я динамически генерирую некоторые типы Java, используя библиотеку генерации байтового кода (Byte Buddy). Естественно, эти файлы классов не имеют соответствующих исходных файлов. Таким образом будет создано только несколько классов. Большая часть кода для этого проекта будет источником Java. В идеале, источник Java будет ссылаться на сгенерированные типы статическим способом, а не на использование генерации кода отражения или времени выполнения, что означает, что классы должны находиться в пути класса компиляции для javac. Могу ли я получить сгенерированные классы в пути класса компиляции для одного и того же проекта Maven, то есть без отдельного проекта Maven и артефакта для хранения сгенерированного байтового кода, на который ссылается проект Maven, содержащий исходный код?Могу ли я динамически генерировать и ссылаться на класс в исходном файле в том же проекте Maven?
UPDATE: Я уже пытался ставить сгенерированные классы непосредственно в target/classes
т.е. project.build.outputDirectory
, в начале Maven сборки Lifecycle, но мне кажется, что не стоит на пути к классу. Сгенерированные типы не могут быть разрешены плагином Maven Compiler или IDE. Я также попытался использовать плагин Build Helper Maven для добавления дополнительного каталога ресурсов под target
, содержащего сгенерированные классы, которые затем автоматически копировались в target/classes
. Эта конфигурация показала ту же проблему.
UPDATE: Я создал полный публичный репозиторий на 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 {
}
сеть/bytebuddy/тест/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.
Возможно, вы можете посмотреть исходный код jax-b: xjc, он делает simil ar thing на этапе генерации-источников – HRgiger