覆盖 Web 项目中使用的库中的 class
Override class in library used in web project
我想修补我在 war 项目中使用的库的 java class。
我已经用具有相同规范名称的新 class 覆盖了 class,但在 Web 应用程序中,原始 class 仍然首先加载。如何控制 class 加载顺序?
我从这个 post 开始,并阅读了有关 JAR Hell 的内容:
Override class in java
并使用此处找到的 Maven 示例:
http://owenou.com/2010/07/20/patching-with-class-shadowing-and-maven.html
基本上是一个辅助项目,它依赖于带有覆盖 class 的新补丁 jar 和原始库,MANIFEST.MF 这些库在 class 中以正确的顺序排列小路。所以其他项目可以使用这个辅助项目。
这在独立应用程序中工作正常,但在 Web 项目中仍然首先加载原始 jar。
有什么帮助吗?
一个肮脏的解决方案是从包含您不想加载的版本的 jar 中删除 class。
另一种解决方案是重新排序 class 路径,使您的版本位于旧版本之前。来自 java documentation:
Specification Order
The order in which you specify multiple class path entries is
important. The Java interpreter will look for classes in the
directories in the order they appear in the class path variable. In
the example above, the Java interpreter will first look for a needed
class in the directory C:\java\MyClasses. Only if it doesn't find a
class with the proper name in that directory will the interpreter look
in the C:\java\OtherClasses directory.
请注意,这两个解决方案都非常脏,将来对代码的修改可能会破坏您的功能(例如更改 classpath 或更新 jar)。
最好的方法是以下之一:
- 扩展 class 并仅使用新的 class
- 在新的 class 中实现相同的界面并使用它
如果您控制应用程序客户端,您可以尝试在运行时使用 jar:
加载时见此
How to load a jar file at runtime
如果您还想卸载:
Dynamic loading and unloading of jar
或者,您可以尝试在 "boot" 处在您的网络应用程序中启动先例技巧。然后你确定你得到了什么类。
我遇到了完全相同的问题,这就是我为使其正常工作所做的工作。
我的项目包括一个 "ThatProject" 库,其中包含 ServiceFactory.java class 导致错误。
<dependencies>
<dependency>
<groupId>com.example.ThatGroup</groupId>
<artifactId>ThatProject</artifactId>
<version>${ThatProject.version}</version>
</dependency>
</dependencies>
在我自己的项目中,我创建了一个相同的 class 来隐藏 "ThatProject" 中的一个(路径必须匹配)。
→ src\main\java\com\example\ThatGroup\ThatProject\ServiceFactory.java
在我的 pom.xml 中,我使用了 maven-shade-plugin 插件,如下所示。
请注意我是如何从 "ThatProject" 库中排除原始 ServiceFactory.java 的。
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<!-- Include all dependencies in JAR -->
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>shade</id>
<goals>
<goal>shade</goal>
</goals>
<phase>package</phase>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<filters>
<filter>
<artifact>com.example.ThatGroup:ThatClient</artifact>
<excludes>
<exclude>com/example/ThatGroup/ThatProject/ServiceFactory.class</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
就是这样,它终于对我有用了。在我的例子中,我将项目的所有文件都包含在 pom.xml 的配置中(包括我的 ServiceFactory.java 的阴影版本)。
如前所述,原始 ServiceFactory.java 在 maven 构建过程中被排除在外。
希望对您有所帮助!
我想修补我在 war 项目中使用的库的 java class。
我已经用具有相同规范名称的新 class 覆盖了 class,但在 Web 应用程序中,原始 class 仍然首先加载。如何控制 class 加载顺序?
我从这个 post 开始,并阅读了有关 JAR Hell 的内容: Override class in java
并使用此处找到的 Maven 示例: http://owenou.com/2010/07/20/patching-with-class-shadowing-and-maven.html
基本上是一个辅助项目,它依赖于带有覆盖 class 的新补丁 jar 和原始库,MANIFEST.MF 这些库在 class 中以正确的顺序排列小路。所以其他项目可以使用这个辅助项目。
这在独立应用程序中工作正常,但在 Web 项目中仍然首先加载原始 jar。
有什么帮助吗?
一个肮脏的解决方案是从包含您不想加载的版本的 jar 中删除 class。
另一种解决方案是重新排序 class 路径,使您的版本位于旧版本之前。来自 java documentation:
Specification Order
The order in which you specify multiple class path entries is important. The Java interpreter will look for classes in the directories in the order they appear in the class path variable. In the example above, the Java interpreter will first look for a needed class in the directory C:\java\MyClasses. Only if it doesn't find a class with the proper name in that directory will the interpreter look in the C:\java\OtherClasses directory.
请注意,这两个解决方案都非常脏,将来对代码的修改可能会破坏您的功能(例如更改 classpath 或更新 jar)。
最好的方法是以下之一:
- 扩展 class 并仅使用新的 class
- 在新的 class 中实现相同的界面并使用它
如果您控制应用程序客户端,您可以尝试在运行时使用 jar:
加载时见此 How to load a jar file at runtime
如果您还想卸载: Dynamic loading and unloading of jar
或者,您可以尝试在 "boot" 处在您的网络应用程序中启动先例技巧。然后你确定你得到了什么类。
我遇到了完全相同的问题,这就是我为使其正常工作所做的工作。 我的项目包括一个 "ThatProject" 库,其中包含 ServiceFactory.java class 导致错误。
<dependencies>
<dependency>
<groupId>com.example.ThatGroup</groupId>
<artifactId>ThatProject</artifactId>
<version>${ThatProject.version}</version>
</dependency>
</dependencies>
在我自己的项目中,我创建了一个相同的 class 来隐藏 "ThatProject" 中的一个(路径必须匹配)。 → src\main\java\com\example\ThatGroup\ThatProject\ServiceFactory.java
在我的 pom.xml 中,我使用了 maven-shade-plugin 插件,如下所示。 请注意我是如何从 "ThatProject" 库中排除原始 ServiceFactory.java 的。
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<!-- Include all dependencies in JAR -->
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>shade</id>
<goals>
<goal>shade</goal>
</goals>
<phase>package</phase>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<filters>
<filter>
<artifact>com.example.ThatGroup:ThatClient</artifact>
<excludes>
<exclude>com/example/ThatGroup/ThatProject/ServiceFactory.class</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
就是这样,它终于对我有用了。在我的例子中,我将项目的所有文件都包含在 pom.xml 的配置中(包括我的 ServiceFactory.java 的阴影版本)。 如前所述,原始 ServiceFactory.java 在 maven 构建过程中被排除在外。
希望对您有所帮助!