Maven编译排除target/generated-sources及生成类迁移问题咨询
src/main/java后的Maven冲突问题 我完全懂你的需求——把生成的Java类纳入版本控制,方便后续自定义修改(加注解、调整代码甚至换插件),但直接复制到src/main/java确实会和插件默认的生成路径产生冲突,因为Maven编译时会同时处理src/main/java和target/generated-sources下的类,导致重复类错误。下面给你几个靠谱的解决方案:
方案1:修改插件生成路径到src/main/java(推荐)
直接让jaxb2-maven-plugin把类生成到src/main/java指定的包路径下,这样就不用手动复制了,生成的类直接在版本控制范围内。你只需要调整插件的配置,指定outputDirectory为src/main/java对应的包目录:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jaxb2-maven-plugin</artifactId> <version>2.5.0</version> <!-- 替换成你当前使用的插件版本 --> <executions> <execution> <goals> <goal>xjc</goal> </goals> </execution> </executions> <configuration> <!-- 你的xsd文件存放路径,按需修改 --> <schemaDirectory>${project.basedir}/src/main/resources/xsd</schemaDirectory> <!-- 直接生成到src/main/java的目标目录 --> <outputDirectory>${project.basedir}/src/main/java</outputDirectory> <!-- 生成类的目标包名,按需修改 --> <packageName>com.yourcompany.yourpackage</packageName> <!-- 关键设置:避免每次构建覆盖你手动修改过的类 --> <clearOutputDir>false</clearOutputDir> </configuration> </plugin>
⚠️ 注意:clearOutputDir设为false非常重要,这样插件不会在每次构建时清空目标目录,你手动添加的注解或代码修改不会被覆盖。如果后续xsd有更新,你需要手动删除旧的生成类再重新生成,或者根据需求临时调整这个参数。
方案2:禁用插件自动生成,完全手动管理类
如果你已经把生成的类复制到src/main/java,并且以后不想再通过插件生成(打算完全手动维护),可以直接从pom.xml中移除jaxb2-maven-plugin的配置,或者把它的执行目标注释掉,这样Maven就不会再生成重复的类了:
<!-- 注释或删除整个插件配置即可 --> <!-- <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jaxb2-maven-plugin</artifactId> ... </plugin> -->
这种方式适合你确定以后不需要再从xsd生成类,完全靠手动修改维护的场景。
方案3:调整Maven编译范围,排除target/generated-sources
如果暂时不想修改插件配置,也可以让Maven编译时忽略target/generated-sources目录,避免重复类冲突。你可以配置maven-compiler-plugin来指定编译源目录:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <sources> <source>${project.basedir}/src/main/java</source> <!-- 移除target/generated-sources,只编译src/main/java下的类 --> </sources> </configuration> </plugin>
不过这种方式不推荐长期使用,因为如果以后又需要从xsd生成类,容易忘记恢复配置,导致生成的类不被编译。
额外建议
- 把生成的类加入版本控制后,最好在项目README里说明这些类的来源(从哪个xsd生成、使用过什么插件),方便后续维护者了解背景。
- 如果以后需要更换生成插件(比如改用maven-jaxb2-plugin),只需要调整插件配置,保持输出路径一致即可,不会影响已有的手动修改。
内容的提问来源于stack exchange,提问作者Tristan

