7

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

所有这一切的唯一好处是我需要更改的类可以正确反编译,所以去了以下内容:

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

由此产生的罐子按预期工作。

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

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

  • 像往常一样编译所有东西,将所有编译好的类文件放入目标文件夹
  • 从目标文件夹中删除存根类文件并用旧的预编译类文件替换它们
  • 包装罐子。

您会推荐哪种方法?

更新

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

所有类都在同一个包中:

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 类没有作为依赖项正确导入,如果我尝试将任何 CustmizableClasses 放入项目源中并让 JiBX 类成为依赖项,编译器会报告缺少方法。

我也尝试按照建议使用 Shade 插件,但是由于我需要将 JiBX 类包含到我的源路径中,我最终不得不将来自 jar 依赖项和编译的 CustomizableClasses 的包 JiBX 类包含到包中,但是从 jar dep 中跳过 CustomizableClasses 并编译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>

谢谢!

卡尔斯

4

1 回答 1

6

我会这样做:

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

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

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

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

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

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

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

对于新 Jar 文件的版本号,我建议使用原始版本的变体。使用相同的groupIdand artifactId,然后修改版本号。如果原始文件有1.0.2,则您的新修补文件应发布为1.0.2-1,以表明它是基于1.0.2源的。如果您需要进行其他更改,请发布该更改,1.0.2-2依此类推。这将使您更容易理解您的补丁所基于的版本,并且递增的补丁编号将为您提供一种区分版本的方法。

于 2013-02-12T11:06:50.350 回答