在Maven Build中,我使用字节代码生成库(Byte Buddy)动态生成一些Java类型.当然,这些类文件没有相应的源文件.这种方式只能生成几个类.该项目的大部分代码都是Java源代码.理想情况下,Java源代码将以静态方式引用生成的类型,而不是使用反射或运行时代码生成,这意味着类需要位于javac的编译类路径上.我是否可以在同一个Maven项目的编译类路径上获取生成的类,即没有单独的Maven项目和工件来保存包含源代码的Maven项目引用的生成的字节代码?
更新:我已经尝试将生成的类直接放入target/classes
ie project.build.outputDirectory
,在Maven Build Lifecycle的早期,但它似乎不在类路径上.Maven编译器插件或 IDE 无法解析生成的类型.我还尝试使用Build Helper Maven插件在target
包含生成的类的情况下添加一个额外的资源目录,然后自动将其复制到该目录中target/classes
.该配置表现出相同的问题.
更新:我在GitHub上创建了一个完整的公共回购:https://github.com/mches/so-42376851
这是项目的Maven POM,我希望有静态类引用字节码增强类:
4.0.0 demo demo 1.0-SNAPSHOT ../pom.xml demo-enhanced org.apache.maven.plugins maven-dependency-plugin generate-resources unpack demo demo-original ${project.version} true ${project.build.outputDirectory} **/*.class META-INF/ net.bytebuddy byte-buddy-maven-plugin process-resources transform net.bytebuddy.test.SimpleEntryPoint demo demo-transformer net.bytebuddy.test.SimplePlugin demo demo-transformer
这是父POM:
4.0.0 demo demo 1.0-SNAPSHOT pom demo-original demo-transformer demo-enhanced UTF-8 1.8 1.8 1.6.9 net.bytebuddy byte-buddy ${byte-buddy.version} demo demo-original ${project.version} demo demo-transformer ${project.version} demo demo-enhanced ${project.version} net.bytebuddy byte-buddy-maven-plugin ${byte-buddy.version}
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); } }
更新: Maven似乎理解一个涉及带有增强字节代码和静态类源代码的整合模块的结构,以及每个模块的单独模块,但IDE,IntelliJ和Eclipse无法理解这两种结构的类路径Maven确实如此.