使用 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