用于Maven shade插件的变换器来处理java反射

时间:2012-01-24 18:26:59

标签: maven maven-plugin

Maven shade插件忽略了Strings中的类/包名称,这是Java反射的典型特征。 如果您尝试“着色”的库使用Class.forName(“originalpackagename ....”),则着色依赖项将不起作用,因为原始包名称将保持不变。 与

等代码相同的故事
servlet.addServletWithMapping("org.mortbay.jetty.servlet.DefaultServlet",
    URIUtil.SLASH);

并使事情变得更糟:

private String[] _serverClasses = {
    "-org.mortbay.jetty.plus.annotation.",       // don't hide
    "-org.mortbay.jetty.plus.jaas.",             // don't hide 
    "-org.mortbay.jetty.plus.naming.",           // don't hide
    "-org.mortbay.jetty.plus.jaas.",             // don't hide
    "-org.mortbay.jetty.servlet.DefaultServlet", // don't hide
    "org.mortbay.jetty.", 
    "org.slf4j."
}; 

(从Jetty服务器源代码复制的示例)

也许有一些已经可用于Maven Shade的ResourceTransformer,它取代了字符串源代码中的原始包/类名??

1 个答案:

答案 0 :(得分:0)

这很可能是自从您提出问题(我使用的是2.3版本)以来的新行为,但是shadow插件似乎会自动处理Java源文件中的包名称文字。

但是,对于资源文件,它不会。例如,如果您尝试对log4j包进行着色,然后从log4j.properties引用logger实现类,则在运行时将出现异常。我没有看到任何专门针对shade插件的内容,但我使用第三方maven-replacer-plugin解决了这个问题。例如:

<plugin>
  <groupId>com.google.code.maven-replacer-plugin</groupId>
  <artifactId>replacer</artifactId>
  <version>1.5.3</version>
  <executions>
    <execution>
      <phase>prepare-package</phase>
      <goals>
        <goal>replace</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <basedir>${project.build.directory}</basedir>
    <includes>
      <include>classes/*.properties</include>
    </includes>
    <replacements>
      <replacement>
        <token>org.</token>
        <value>my-shaded-package-root.org.</value>
      </replacement>
    </replacements>
  </configuration>
</plugin>