我面临着一个非常独特的情况,需要一些建议: 我正在开发一个项目,该项目依赖于同一家公司的另一个项目,现在我需要对依赖项进行一些修改。 我遇到的问题是依赖项的源代码已经丢失,所以我唯一拥有的就是存储库中的 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 文件的变体。使用相同的groupId
和artifactId
,然后修改版本号。如果原件有1.0.2
,您的新修补文件应发布为 1.0.2-1
,表明它基于 1.0.2
来源。如果您需要进行其他更改,请将其发布为 1.0.2-2
等等。这将使您轻松了解您的补丁基于哪个版本,并且递增的补丁号将为您提供区分版本的方法。
关于class - 在maven组装之前替换类文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14830687/