使用 Maven 动态加载 类 的 Jar 着色
Jar Shading With Dynamically Loaded Classes With Maven
在将 jar 上传到 AWS lambda 之前,我正在使用 maven 插件对其进行着色和最小化。但是,由于缺少 class,我遇到了 运行time 异常。据我所知,这是由于某些 'dynamic' class 加载或其他原因造成的,但我不确定 A) 是否有解决方案或 B) 它可能是什么,超出了我的努力已经做了。我读了一些关于 jar 着色的好[文章][1],我想我理解了一般的想法,但我找不到任何地方记录的我的特定问题的例子。
[INFO] Replacing original artifact with shaded artifact.
[INFO] Replacing /home/ro007848/Workspace/geometry-service/target/geometry-service-1.0.0.jar with /home/ro007848/Workspace/geometry-service/target/geometry-service-1.0.0-shaded.jar
下面是我在 cloudwatch 中看到的堆栈跟踪:
Caused by: java.lang.RuntimeException: Unable to find function Length
at org.geotools.filter.FunctionFinder.findFunction(FunctionFinder.java:208)
at org.geotools.filter.FunctionFinder.findFunction(FunctionFinder.java:152)
at org.geotools.filter.FunctionFinder.findFunction(FunctionFinder.java:129)
at org.geotools.filter.FilterFactoryImpl.function(FilterFactoryImpl.java:819)
at org.geotools.feature.FeatureTypes.createLengthRestriction(FeatureTypes.java:148)
这是我的 pom 文件的内容:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
<filters>
<filter>....</filter>
<filter>
<artifact>org.geotools:*</artifact>
<includes>
<include>**</include>
</includes>
</filter>
..........
<filter>....</filter>
<filter>
<artifact>com.amazonaws:*</artifact>
<includes>
<include>**</include>
</includes>
</filter>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
当我拿到生成的 jar 时,解压并查看里面,
➜ geotools git:(dev-S62039_geojson-to-shapefile_ro007848) ✗ pwd
/home/ro007848/Workspace/geometry-service/target/jar-shaded-simple/jar-contents/org/geotools
➜ geotools git:(dev-S62039_geojson-to-shapefile_ro007848) ✗ grep -r "Length"
这是我找到的:
................
Binary file ows/wms/CRSEnvelope.class matches
Binary file filter/FilterSAXParser.class matches
Binary file filter/FilterDOMParser.class matches
Binary file filter/LengthFunction.class matches
Binary file filter/function/StaticGeometry.class matches
Binary file filter/function/FilterFunction_strLength.class matches
Binary file filter/function/FilterFunction_strToLowerCase.class matches
Binary file filter/function/FilterFunction_strToUpperCase.class matches
Binary file filter/function/FilterFunction_geomLength.class matches
Binary file filter/ExpressionDOMParser.class matches
Binary file referencing/util/CRSUtilities.class matches
Binary file referencing/crs/DefaultProjectedCRS.class matches
................
好像那里有一个“长度”函数...如果我的异常不是在谈论这个,它在谈论哪个?我如何调试这个问题?是否有 'scorched-earth' 方法在 jar-shading 插件配置中设置 <include>
过滤器以便让它工作?
其他人建议我尝试在着色配置中显式添加这些 classes,如下所示:
<filter>
<artifact>org.geotools:gt-main</artifact>
<includes>
<include>org/geotools/filter/LengthFunction.class</include>
</includes>
</filter>
但这要么不起作用,要么我做的不对。
更多信息:
我运行在本地对这段代码进行集成测试时,执行没有问题。找到所需的任何功能。但是,当我对我在 AWS 中部署的资源(由这个 jar 支持的这个 lambda)执行相同的集成测试时,那就是 当我失败时。我发现很难在调试器中发现很多我需要包含的内容,因为代码似乎可以做一些事情 'dynamically' 而我无法密切关注它。
我已经无计可施了!
编辑:
我查看了@gerold-broser 发布的电子邮件线程,但我不确定它是否适用,因为根据 mvn help:effective-pom -Dverbose
我使用的是 geotools 25.1 版。输出显示
<dependency>
<groupId>org.geotools</groupId> <!-- com.digitalglobe.p2020.common:common-dependencies:3.47.139813, line 922 -->
<artifactId>gt-coverage</artifactId> <!-- com.digitalglobe.p2020.common:common-dependencies:3.47.139813, line 923 -->
<version>25.1</version> <!-- com.digitalglobe.p2020.common:common-dependencies:3.47.139813, line 924 -->
</dependency>
``` and
```
<dg-geotools.version>25.1</dg-geotools.version> <!-- com.digitalglobe.p2020.common:common-dependencies:3.47.139813, line 218 -->
```
[1]: https://medium.com/@akhaku/java-class-shadowing-and-shading-9439b0eacb13
正如在 GeoTools FAQ 中讨论的那样,GeoTools 依赖于您的应用程序使用的每个 GeoTools 模块中的 META-INF/services
文件。除非你特别指示 Shade
插件合并这些文件,否则你将得到 Maven 看到的第一个或最后一个文件(我忘了是哪个)。
因此将此添加到您的 pom 的 build
部分:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.3.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<!-- This bit merges the various GeoTools META-INF/services files -->
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
如果您想检查它是否有效,那么您需要检查 META-INF/services/org.opengis.filter.expression.Function
是否包括 org.geotools.filter.LengthFunction
在将 jar 上传到 AWS lambda 之前,我正在使用 maven 插件对其进行着色和最小化。但是,由于缺少 class,我遇到了 运行time 异常。据我所知,这是由于某些 'dynamic' class 加载或其他原因造成的,但我不确定 A) 是否有解决方案或 B) 它可能是什么,超出了我的努力已经做了。我读了一些关于 jar 着色的好[文章][1],我想我理解了一般的想法,但我找不到任何地方记录的我的特定问题的例子。
[INFO] Replacing original artifact with shaded artifact.
[INFO] Replacing /home/ro007848/Workspace/geometry-service/target/geometry-service-1.0.0.jar with /home/ro007848/Workspace/geometry-service/target/geometry-service-1.0.0-shaded.jar
下面是我在 cloudwatch 中看到的堆栈跟踪:
Caused by: java.lang.RuntimeException: Unable to find function Length
at org.geotools.filter.FunctionFinder.findFunction(FunctionFinder.java:208)
at org.geotools.filter.FunctionFinder.findFunction(FunctionFinder.java:152)
at org.geotools.filter.FunctionFinder.findFunction(FunctionFinder.java:129)
at org.geotools.filter.FilterFactoryImpl.function(FilterFactoryImpl.java:819)
at org.geotools.feature.FeatureTypes.createLengthRestriction(FeatureTypes.java:148)
这是我的 pom 文件的内容:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
<filters>
<filter>....</filter>
<filter>
<artifact>org.geotools:*</artifact>
<includes>
<include>**</include>
</includes>
</filter>
..........
<filter>....</filter>
<filter>
<artifact>com.amazonaws:*</artifact>
<includes>
<include>**</include>
</includes>
</filter>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
当我拿到生成的 jar 时,解压并查看里面,
➜ geotools git:(dev-S62039_geojson-to-shapefile_ro007848) ✗ pwd
/home/ro007848/Workspace/geometry-service/target/jar-shaded-simple/jar-contents/org/geotools
➜ geotools git:(dev-S62039_geojson-to-shapefile_ro007848) ✗ grep -r "Length"
这是我找到的:
................
Binary file ows/wms/CRSEnvelope.class matches
Binary file filter/FilterSAXParser.class matches
Binary file filter/FilterDOMParser.class matches
Binary file filter/LengthFunction.class matches
Binary file filter/function/StaticGeometry.class matches
Binary file filter/function/FilterFunction_strLength.class matches
Binary file filter/function/FilterFunction_strToLowerCase.class matches
Binary file filter/function/FilterFunction_strToUpperCase.class matches
Binary file filter/function/FilterFunction_geomLength.class matches
Binary file filter/ExpressionDOMParser.class matches
Binary file referencing/util/CRSUtilities.class matches
Binary file referencing/crs/DefaultProjectedCRS.class matches
................
好像那里有一个“长度”函数...如果我的异常不是在谈论这个,它在谈论哪个?我如何调试这个问题?是否有 'scorched-earth' 方法在 jar-shading 插件配置中设置 <include>
过滤器以便让它工作?
其他人建议我尝试在着色配置中显式添加这些 classes,如下所示:
<filter>
<artifact>org.geotools:gt-main</artifact>
<includes>
<include>org/geotools/filter/LengthFunction.class</include>
</includes>
</filter>
但这要么不起作用,要么我做的不对。
更多信息:
我运行在本地对这段代码进行集成测试时,执行没有问题。找到所需的任何功能。但是,当我对我在 AWS 中部署的资源(由这个 jar 支持的这个 lambda)执行相同的集成测试时,那就是 当我失败时。我发现很难在调试器中发现很多我需要包含的内容,因为代码似乎可以做一些事情 'dynamically' 而我无法密切关注它。
我已经无计可施了!
编辑:
我查看了@gerold-broser 发布的电子邮件线程,但我不确定它是否适用,因为根据 mvn help:effective-pom -Dverbose
我使用的是 geotools 25.1 版。输出显示
<dependency>
<groupId>org.geotools</groupId> <!-- com.digitalglobe.p2020.common:common-dependencies:3.47.139813, line 922 -->
<artifactId>gt-coverage</artifactId> <!-- com.digitalglobe.p2020.common:common-dependencies:3.47.139813, line 923 -->
<version>25.1</version> <!-- com.digitalglobe.p2020.common:common-dependencies:3.47.139813, line 924 -->
</dependency>
``` and
```
<dg-geotools.version>25.1</dg-geotools.version> <!-- com.digitalglobe.p2020.common:common-dependencies:3.47.139813, line 218 -->
```
[1]: https://medium.com/@akhaku/java-class-shadowing-and-shading-9439b0eacb13
正如在 GeoTools FAQ 中讨论的那样,GeoTools 依赖于您的应用程序使用的每个 GeoTools 模块中的 META-INF/services
文件。除非你特别指示 Shade
插件合并这些文件,否则你将得到 Maven 看到的第一个或最后一个文件(我忘了是哪个)。
因此将此添加到您的 pom 的 build
部分:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.3.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<!-- This bit merges the various GeoTools META-INF/services files -->
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
如果您想检查它是否有效,那么您需要检查 META-INF/services/org.opengis.filter.expression.Function
是否包括 org.geotools.filter.LengthFunction