class - 在maven组装之前替换类文件

标签 class maven jar resources package

我面临着一个非常独特的情况,需要一些建议: 我正在开发一个项目,该项目依赖于同一家公司的另一个项目,现在我需要对依赖项进行一些修改。 我遇到的问题是依赖项的源代码已经丢失,所以我唯一拥有的就是存储库中的 Maven 依赖项以及相应的 jar 文件。 最重要的是,Jar 文件中的一些类是使用 JiBX 解析器创建的,映射了一些我没有的 XSD 文件,并且生成的类是合成的,我发现没有反编译器能够正确处理它们。

所有这一切中唯一的好处是我需要更改的类可以正确反编译,因此进行了以下操作:

  • 我反编译了整个 jar 文件并最终得到了一些类( JiBx 的)具有空的或错误实现的方法。
  • 我注释掉了错误方法的主体以获取 stub 对象,将所需的更改应用到正确的类并重新编译。
  • 我取出旧的 Jar 文件,打开它并手动用新的类替换旧的类。

生成的 Jar 按预期工作。

现在我的问题是:我可以使用 Maven 完成所有这些工作吗?

这个想法是将 JiBX 类文件作为资源,并将 stub 等效项保留为源文件,然后让 maven:

  • 照常编译所有内容,放入所有已编译的类文件 进入目标文件夹
  • 从目标文件夹中删除 stub 类文件,并将其替换为旧的预编译类文件
  • 打包 jar。

您会推荐哪种方法?

更新

我提供了有关依赖项目结构的更多详细信息:

所有类都在同一个包内:

my.project.domain.JiBX__c_GeneratedObfuscatedClass1.java
my.project.domain.JiBX__c_GeneratedObfuscatedClass2.java
my.project.domain.JiBX__c_GeneratedObfuscatedClass3.java
my.project.domain.CustomizableClass1.java
my.project.domain.CustomizableClass2.java
my.project.domain.CustomizableClass3.java

JiBX 类未作为依赖项正确导入,如果我尝试将任何 CustmizableClass 放入项目源中并让 JiBX 类处于依赖项中,编译器会报告缺少方法。

我还尝试按照建议使用 Shade 插件,但由于我需要将 JiBX 类包含到我的源路径中,因此我最终必须将 jar 依赖项中的 JiBX 类包含到包中并编译可定制类,但从 jar 中跳过可定制类dep 并编译了 JiBX 类。

我看起来可以工作,但我承认我仍然没有找到做到这一点的方法。 任何线索都将非常受欢迎。

更新 2(解决方案)

我在这里解释了我最终如何使用建议的阴影插件来管理这个问题,以防万一其他人也需要这样做:

我最终创建了一个项目,将反编译的类放在同一个包中,并将不想反编译的方法注释掉。

在 pom.xml 中我添加了以下内容:

<build>
<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>2.0</version>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>shade</goal>
                </goals>
                <configuration>
                    <artifactSet>
                        <includes>
                            <include>${project.groupId}:${project.artifactId}</include>
                            <include>TheDamnedProject:WithoutSources</include>
                        </includes>
                    </artifactSet>
                    <filters>
                        <filter>
                            <artifact>TheDamnedProject:WithoutSources</artifact>
                            <includes>
                                <!-- These classes will be taken directly from dependency JAR -->
                                <include>my/package/ClassWhichCouldNotBeDecompiled1.class</include>
                                <include>my/package/ClassWhichCouldNotBeDecompiled2.class</include>
                                <include>my/package/ClassWhichCouldNotBeDecompiled3.class</include>
                                <include>my/package/ClassWhichCouldNotBeDecompiled4.class</include>
                            </includes>
                        </filter>
                        <filter>
                            <artifact>${project.groupId}:${project.artifactId}</artifact>
                            <excludes>
                                <!-- These classes will be overridden by the ones inside the JAR -->
                                <exclude>my/package/ClassWhichCouldNotBeDecompiled1.class</exclude>
                                <exclude>my/package/ClassWhichCouldNotBeDecompiled2.class</exclude>
                                <exclude>my/package/ClassWhichCouldNotBeDecompiled3.class</exclude>
                                <exclude>my/package/ClassWhichCouldNotBeDecompiled4.class</exclude>
                            </excludes>
                        </filter>
                    </filters>
                </configuration>
            </execution>
        </executions>
    </plugin>
</plugins>

谢谢!

卡尔斯

最佳答案

我会这样做:

  • 为此 Jar 文件创建一个新的 Maven 项目,打包类型为 jar
  • 包含原始 Jar 文件作为依赖项
  • 在src文件夹中添加一个反编译的.java文件

这应该可以让您编译 .java 文件,因为 jar 文件中的其他类都可用。

您现在有两个 Jar 文件:一个是原始文件,另一个应该只包含单个重新编译和更改的类。

将两者添加到应用程序类路径中可能会起作用,但这取决于类路径上的顺序。

如果您想最终得到一个 jar 文件,我建议您看一下 Maven Shade 插件 ( http://maven.apache.org/plugins/maven-shade-plugin/ ),它允许您创建一个包含内容的新 Jar 文件来自多个来源。它将允许您过滤进入新 Jar 文件的内容。

Maven Shade 插件允许您指定包含每个 Artifact 中的哪些类。它为此使用通配符和包含/排除标签,如下所述: http://maven.apache.org/plugins/maven-shade-plugin/examples/includes-excludes.html

创建 Jar 文件后,我将使用 Maven 发布插件发布它,然后将该 Artifact 包含在下游。这将允许您仅在真正需要时更新已修补的 Jar,它可能不必在每个构建上都更新。但这取决于您的使用模式。

对于新 Jar 文件的版本号,我建议使用原始 Jar 文件的变体。使用相同的groupIdartifactId ,然后修改版本号。如果原件有1.0.2 ,您的新修补文件应发布为 1.0.2-1 ,表明它基于 1.0.2来源。如果您需要进行其他更改,请将其发布为 1.0.2-2等等。这将使您轻松了解您的补丁基于哪个版本,并且递增的补丁号将为您提供区分版本的方法。

关于class - 在maven组装之前替换类文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14830687/

相关文章:

java - 运行 jar 不起作用

linux - 以不同的用户身份启动 .jar

c++ - 静态常量字符串(类成员)

java - 处理序列化框架不兼容的版本更改

java - Maven onejar插件,获取属性文件

java - 我可以根据平台定制 Maven 构建吗?

java - 无法读取可运行的 Jar 文件

c++ - 在模板类构造函数中创建一个计数器

CSS Hover 不接受类名

Python - 检查图是否已连接 - 意外的循环行为