java - 使用 Maven 动态加载类的 Jar 着色
问题描述
在将 jar 上传到 AWS lambda 之前,我正在使用 maven 插件对其进行遮蔽和最小化。但是,由于缺少类,我遇到了运行时异常。据我所知,这是由于一些“动态”类加载或其他原因,但我不确定 A)是否有解决方案或 B)它可能是什么,超出了我已经做出的努力。我阅读了一些关于 jar 着色的好 [articles][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>
当我拿起生成的罐子,解压缩并查看内部时,
➜ 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
................
似乎那里有一个“长度”功能......如果我的例外不是在谈论这个,那么它在谈论哪一个?我该如何调试这个问题?是否有“焦土”方法<include>
在 jar-shading 插件配置中设置过滤器,以便使其正常工作?
其他人建议我尝试在着色配置中显式添加这些类,如下所示:
<filter>
<artifact>org.geotools:gt-main</artifact>
<includes>
<include>org/geotools/filter/LengthFunction.class</include>
</includes>
</filter>
但这要么不起作用,要么我做得不对。
更多信息:
当我在本地对此代码运行集成测试时,执行没有问题。找到所需的任何功能。但是,当我对部署在 AWS 中的资源(由这个 jar 支持的一个 lambda)执行相同的集成测试时,我就遇到了失败。我发现很难在调试器中发现很多我需要包含的内容,因为代码似乎是“动态地”做事的,而且我很难密切关注它。
我无计可施!
编辑:我查看了@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 依赖于META-INF/services
您的应用程序使用的每个 GeoTools 模块中的文件。除非您特别指示Shade
插件合并这些文件,否则您最终会得到 maven 看到的第一个或最后一个(我忘记了)。
因此,将其添加到您的 pombuild
部分:
<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
推荐阅读
- haskell - 在haskell中搜索序列是否比向量快?
- java - 重载和 Java 类型概念
- azure - Azure Cosmos DB:Application Insights 中的 HTTP 400
- python - 按字母顺序对 csv 文件进行排序
- hyperledger-fabric - 在 fabcar.js 中添加数据
- mysql - 怎么了,我把所有的名字都记了两次?
- python - JSON相机点结构TypeError:预期的字符串或缓冲区
- qt - 带有 QtCreator 的 GDB 无法读取变量
- list - 从熊猫数据框创建列表
- regex - 带有换行符的匹配字符串的正则表达式