在 maven 中创建并安装 de-lomboked 源 jar
Create and install de-lomboked source jar in maven
Disclaimer: I have solved this problem and am documenting the solution for the world to know.
如何在 Maven 中创建和安装包含 "delomboked" 源代码的 *-sources.jar
?
默认情况下,maven-source-plugin 会创建源 jar 而不删除源文件,这会导致依赖库二进制文件的项目抱怨源文件不匹配。
TL;DR(解释如下)
将以下插件配置添加到 pom.xml
的 project.build
元素中的 plugins
配置
<project>
...
<build>
<plugins>
...
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>1.18.0.0</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>delombok</goal>
</goals>
</execution>
</executions>
<configuration>
<sourceDirectory>src/main/java</sourceDirectory>
<outputDirectory>${project.build.directory}/delombok</outputDirectory>
<addOutputDirectory>false</addOutputDirectory>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>copy-to-lombok-build</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
</resources>
<outputDirectory>${project.build.directory}/delombok</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>generate-delomboked-sources-jar</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<jar destfile="${project.build.directory}/${project.build.finalName}-sources.jar"
basedir="${project.build.directory}/delombok"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>install-source-jar</id>
<goals>
<goal>install-file</goal>
</goals>
<phase>install</phase>
<configuration>
<file>${project.build.directory}/${project.build.finalName}-sources.jar</file>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<classifier>sources</classifier>
<generatePom>true</generatePom>
<pomFile>${project.basedir}/pom.xml</pomFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
说明
lombok-maven-plugin
将使您能够 delombok 源代码 (${project.basedir}/src/main/java
) 并将其放置在目标目录 (${project.build.directory}/delombok
) 中。通常这会将代码放在 ${project.build.directory}/generated-sources/delombok
文件夹中,但是因为 Intellij 会自动考虑这个额外的源代码,所以在开发库时会出现重复代码错误,为了停止这种情况,只需指定一个非默认目标目录(在这种情况下,就在 generated-sources
目录之外)。
maven-resources-plugin
是必要的,以便从标准 ${project.basedir}/src/main/resources
目录复制资源。如果你的项目中有其他非标准的资源目录,你应该在这个插件的资源部分配置它们。
使用maven-antrun-plugin
代替maven-source-plugin,因为后面不能指定自定义源码目录。 jar 任务指向我们的自定义 "generated-sources" 并生成标准命名的源 jar。
使用 maven-install-plugin
install-file
目标是因为您无法使用 install
目标附加 jar。我们可以通过使用 install-file
目标和分类器 sources
.
手动安装文件来破解解决方案
我希望这能帮助像我一样遇到这个问题的其他人。
以下解决方案基于上面提供的解决方案,但通过使用 build-helper 插件附加生成的 delomboked 源 jar 而不是使用安装文件对其进行了改进。这样做的好处是正常的 Maven 安装和部署阶段可以正确处理生成的文件,就像使用源插件一样。
<project>
...
<build>
<plugins>
...
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>1.18.12.0</version>
<executions>
<execution>
<id>delombok-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>delombok</goal>
</goals>
<configuration>
<sourceDirectory>src/main/java</sourceDirectory>
<outputDirectory>${project.build.directory}/delombok</outputDirectory>
<addOutputDirectory>false</addOutputDirectory>
<encoding>UTF-8</encoding>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>generate-delomboked-sources-jar</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<jar destfile="${project.build.directory}/${project.build.finalName}-sources.jar"
basedir="${project.build.directory}/delombok"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>attach-delomboked-sources-jar</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/${project.build.finalName}-sources.jar</file>
<type>jar</type>
<classifier>sources</classifier>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
对于多模块项目或纯 pom 项目,这两个答案都是有缺陷的,因为没有源,所以你必须创建一个空目录,它会产生一个空的 .jar。
有一种简单(但有点复杂)的方法可以实现您想要的功能:制作您自己的 Maven Plugin
。
听起来过于复杂,但我们可以重新使用 maven-sources-plugin
并通过 MOJO 的继承更新必要的部分:
import java.util.List;
import java.util.stream.Collectors;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.source.SourceJarNoForkMojo;
import org.apache.maven.project.MavenProject;
/**
* This goal bundles all the sources into a jar archive, but uses delomboked sources.
*/
@Mojo(name = "jar-no-fork", defaultPhase = LifecyclePhase.VERIFY, threadSafe = true)
public class EnhancedSourceJarNoForkMojo extends SourceJarNoForkMojo {
@Parameter(property = "<some-prefix>.useDelombokSources", defaultValue = "true")
protected boolean useDelombokSources;
@Parameter(property = "<some-prefix>.delombokSourcesLocation", defaultValue = "delombok")
protected String delombokSourcesLocation;
@Override
protected List<String> getSources(MavenProject p) {
// if user doesn't want delomboked sources, use default algorithm
List<String> sources = super.getSources(p);
if (!useDelombokSources) {
return sources;
}
// typically, sources' list will contain: [src/main/java, target/generated_sources].
// replace src/main/java if it's present with delombok-generated sources
String target = p.getBuild().getDirectory();
return super.getSources(p)
.stream()
.map(s -> s.endsWith("java") ? String.format("%s/%s", target, delombokSourcesLocation) : s)
.collect(Collectors.toList());
}
}
pom.xml 例程的要点是 available here。
想指出的是,也可以使用配置文件(绕过不可自定义的构建源目录)。 https://sudonull.com/post/1197-Lombok-sourcesjar-and-convenient-debug
中描述了解决方案
将以下内容添加到 pom.xml
属性:
<origSourceDir>${project.basedir}/src/main/java</origSourceDir>
<sourceDir>${origSourceDir}</sourceDir>
<delombokedSourceDir>${project.build.directory}/delombok</delombokedSourceDir>
</properties>
配置文件和构建部分更改:
<profiles>
<profile>
<id>build</id>
<properties>
<sourceDir>${delombokedSourceDir}</sourceDir>
</properties>
</profile>
</profiles>
<build>
<sourceDirectory>${sourceDir}</sourceDirectory>
<plugins>
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>1.18.20.0</version>
<executions>
<execution>
<id>delombok</id>
<phase>generate-sources</phase>
<goals>
<goal>delombok</goal>
</goals>
<configuration>
<addOutputDirectory>false</addOutputDirectory>
<sourceDirectory>${origSourceDir}</sourceDirectory>
<outputDirectory>${delombokedSourceDir}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
执行mvn clean install -Pbuild
这应该可以解决 IntelliJ 中的“库源与 class 的字节码不匹配”错误,并在大多数情况下允许无缝调试。
Disclaimer: I have solved this problem and am documenting the solution for the world to know.
如何在 Maven 中创建和安装包含 "delomboked" 源代码的 *-sources.jar
?
默认情况下,maven-source-plugin 会创建源 jar 而不删除源文件,这会导致依赖库二进制文件的项目抱怨源文件不匹配。
TL;DR(解释如下)
将以下插件配置添加到 pom.xml
的project.build
元素中的 plugins
配置
<project>
...
<build>
<plugins>
...
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>1.18.0.0</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>delombok</goal>
</goals>
</execution>
</executions>
<configuration>
<sourceDirectory>src/main/java</sourceDirectory>
<outputDirectory>${project.build.directory}/delombok</outputDirectory>
<addOutputDirectory>false</addOutputDirectory>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>copy-to-lombok-build</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
</resources>
<outputDirectory>${project.build.directory}/delombok</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>generate-delomboked-sources-jar</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<jar destfile="${project.build.directory}/${project.build.finalName}-sources.jar"
basedir="${project.build.directory}/delombok"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>install-source-jar</id>
<goals>
<goal>install-file</goal>
</goals>
<phase>install</phase>
<configuration>
<file>${project.build.directory}/${project.build.finalName}-sources.jar</file>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<classifier>sources</classifier>
<generatePom>true</generatePom>
<pomFile>${project.basedir}/pom.xml</pomFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
说明
lombok-maven-plugin
将使您能够 delombok 源代码 (${project.basedir}/src/main/java
) 并将其放置在目标目录 (${project.build.directory}/delombok
) 中。通常这会将代码放在 ${project.build.directory}/generated-sources/delombok
文件夹中,但是因为 Intellij 会自动考虑这个额外的源代码,所以在开发库时会出现重复代码错误,为了停止这种情况,只需指定一个非默认目标目录(在这种情况下,就在 generated-sources
目录之外)。
maven-resources-plugin
是必要的,以便从标准 ${project.basedir}/src/main/resources
目录复制资源。如果你的项目中有其他非标准的资源目录,你应该在这个插件的资源部分配置它们。
maven-antrun-plugin
代替maven-source-plugin,因为后面不能指定自定义源码目录。 jar 任务指向我们的自定义 "generated-sources" 并生成标准命名的源 jar。
maven-install-plugin
install-file
目标是因为您无法使用 install
目标附加 jar。我们可以通过使用 install-file
目标和分类器 sources
.
我希望这能帮助像我一样遇到这个问题的其他人。
以下解决方案基于上面提供的解决方案,但通过使用 build-helper 插件附加生成的 delomboked 源 jar 而不是使用安装文件对其进行了改进。这样做的好处是正常的 Maven 安装和部署阶段可以正确处理生成的文件,就像使用源插件一样。
<project>
...
<build>
<plugins>
...
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>1.18.12.0</version>
<executions>
<execution>
<id>delombok-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>delombok</goal>
</goals>
<configuration>
<sourceDirectory>src/main/java</sourceDirectory>
<outputDirectory>${project.build.directory}/delombok</outputDirectory>
<addOutputDirectory>false</addOutputDirectory>
<encoding>UTF-8</encoding>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>generate-delomboked-sources-jar</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<jar destfile="${project.build.directory}/${project.build.finalName}-sources.jar"
basedir="${project.build.directory}/delombok"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>attach-delomboked-sources-jar</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/${project.build.finalName}-sources.jar</file>
<type>jar</type>
<classifier>sources</classifier>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
对于多模块项目或纯 pom 项目,这两个答案都是有缺陷的,因为没有源,所以你必须创建一个空目录,它会产生一个空的 .jar。
有一种简单(但有点复杂)的方法可以实现您想要的功能:制作您自己的 Maven Plugin
。
听起来过于复杂,但我们可以重新使用 maven-sources-plugin
并通过 MOJO 的继承更新必要的部分:
import java.util.List;
import java.util.stream.Collectors;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.source.SourceJarNoForkMojo;
import org.apache.maven.project.MavenProject;
/**
* This goal bundles all the sources into a jar archive, but uses delomboked sources.
*/
@Mojo(name = "jar-no-fork", defaultPhase = LifecyclePhase.VERIFY, threadSafe = true)
public class EnhancedSourceJarNoForkMojo extends SourceJarNoForkMojo {
@Parameter(property = "<some-prefix>.useDelombokSources", defaultValue = "true")
protected boolean useDelombokSources;
@Parameter(property = "<some-prefix>.delombokSourcesLocation", defaultValue = "delombok")
protected String delombokSourcesLocation;
@Override
protected List<String> getSources(MavenProject p) {
// if user doesn't want delomboked sources, use default algorithm
List<String> sources = super.getSources(p);
if (!useDelombokSources) {
return sources;
}
// typically, sources' list will contain: [src/main/java, target/generated_sources].
// replace src/main/java if it's present with delombok-generated sources
String target = p.getBuild().getDirectory();
return super.getSources(p)
.stream()
.map(s -> s.endsWith("java") ? String.format("%s/%s", target, delombokSourcesLocation) : s)
.collect(Collectors.toList());
}
}
pom.xml 例程的要点是 available here。
想指出的是,也可以使用配置文件(绕过不可自定义的构建源目录)。 https://sudonull.com/post/1197-Lombok-sourcesjar-and-convenient-debug
中描述了解决方案将以下内容添加到 pom.xml 属性:
<origSourceDir>${project.basedir}/src/main/java</origSourceDir>
<sourceDir>${origSourceDir}</sourceDir>
<delombokedSourceDir>${project.build.directory}/delombok</delombokedSourceDir>
</properties>
配置文件和构建部分更改:
<profiles>
<profile>
<id>build</id>
<properties>
<sourceDir>${delombokedSourceDir}</sourceDir>
</properties>
</profile>
</profiles>
<build>
<sourceDirectory>${sourceDir}</sourceDirectory>
<plugins>
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>1.18.20.0</version>
<executions>
<execution>
<id>delombok</id>
<phase>generate-sources</phase>
<goals>
<goal>delombok</goal>
</goals>
<configuration>
<addOutputDirectory>false</addOutputDirectory>
<sourceDirectory>${origSourceDir}</sourceDirectory>
<outputDirectory>${delombokedSourceDir}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
执行mvn clean install -Pbuild
这应该可以解决 IntelliJ 中的“库源与 class 的字节码不匹配”错误,并在大多数情况下允许无缝调试。