在Maven中创建并安装去笨拙的源jar

时间:2018-09-17 07:05:34

标签: java maven lombok

  

免责声明:我已经解决了这个问题,并在记录解决方案,供全世界了解。

我如何在maven中创建并安装包含“删除”源代码的 *-sources.jar

默认情况下,maven-source-plugin会创建一个源jar,而不会释放源文件,这会导致依赖库二进制文件的项目抱怨源文件不匹配。

4 个答案:

答案 0 :(得分:4)

以下解决方案基于上述提供的解决方案,但是通过使用build-helper插件来附加生成的delomboked源jar而不是使用install-file来改进了该解决方案。这样做的好处是,正常的maven安装和部署阶段可以正确处理生成的文件,就像使用了source插件一样。

<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>

答案 1 :(得分:2)

TL; DR(在下面解释)

在pom.xml的plugins元素的project.build配置中添加以下插件配置

<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 使您可以释放源代码(${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任务指向我们的自定义“生成源”,并生成标准命名的源jar。

maven-install-plugin 使用install-file目标是因为您不能使用install目标附加罐子。我们可以通过使用install-file目标和分类器sources手动安装文件来破解解决方案。

我希望这能帮助像我一样在挣扎中挣扎的其他人。

答案 2 :(得分:1)

想指出还可以使用配置文件(以绕过无法自定义的构建源目录)。解决方案在 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 中的“库源与类的字节码不匹配”错误,并在大多数情况下允许无缝调试。

参考:“Delombok plugin + profile in maven

答案 3 :(得分:0)

这两个答案对于多模块项目或纯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