creating an uber jar with spring dependencies

蹲街弑〆低调 提交于 2019-11-28 05:23:21

问题


I'm trying to create an application über jar, but running into an issue due to a dependency on the spring framework. In particular, the namespaces for the xml schemas are problematic. You get the infamous NamespaceHandler problem:

Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/c]

For creating (simple) uber jars, Creating a bundle jar with ant, but this doesn't work if you have spring dependencies due to the fact that the spring jars have files such as spring.handlers, spring.schemas and spring.tooling in the META-INF directories of many of their jar files. The namespace resolution is dependent, I believe, on these files.

The über jar seems to somehow contain all necessary files, but I'm guessing the runtime is seeing only one.

For example, a jar -tf of my uber jar shows (in part)

META-INF/spring.handlers
META-INF/spring.schemas
META-INF/spring.tooling
META-INF/license.txt
META-INF/notice.txt
META-INF/spring.factories
META-INF/spring.handlers
META-INF/spring.schemas
META-INF/spring.tooling
META-INF/license.txt
META-INF/notice.txt
META-INF/license.txt
META-INF/notice.txt
META-INF/spring.handlers
META-INF/spring.schemas
META-INF/spring.tooling
META-INF/license.txt
META-INF/notice.txt
META-INF/license.txt

So: question.. is there a way to create an uber-jar that has the spring jars bundled inside? Do I need to merge the META-INF files? Anyone have experience doing file merger with ant builds?


回答1:


Well.. this was a pain.

<target name="make-bundle" depends="jar">
  <!-- retrieve the dependencies -->
  <ivy:retrieve conf="deploy" pattern="${dist.dir}/dependencies/[artifact].[ext]"/>

  <delete dir="${dist.dir}/dependencies/uber" failonerror="false" />
  <mkdir dir="${dist.dir}/dependencies/uber"/> 
  <!-- iterate over the dependencies -->
  <for param="file">
    <path>
      <fileset dir="${dist.dir}/dependencies"> 
        <include name="**/*.jar"/> 
      </fileset> 
    </path>
    <sequential> 
      <propertyregex override="yes" 
        property="jarname"  input="@{file}" 
        regexp=".*/([^/]*)\.jar" replace="\1"/> 

      <!-- put the spring.* jars into special sub-directories -->
      <mkdir dir="${dist.dir}/dependencies/${jarname}"/> 
      <unzip dest="${dist.dir}/dependencies/${jarname}" src="@{file}">
        <patternset>
          <include name="**/META-INF/spring.*"/>
        </patternset>
      </unzip>
      <!-- put everything else in the 'uber' directory -->
      <unzip dest="${dist.dir}/dependencies/uber" src="@{file}">
        <patternset>
          <exclude name="**/META-INF/spring.*"/>
        </patternset>
        </unzip>
    </sequential>
  </for>

  <!-- build the concatenated spring.* files -->
  <mkdir dir="${dist.dir}/dependencies/META-INF"/> 
  <concat destfile="${dist.dir}/dependencies/META-INF/spring.handlers" fixlastline="true">
    <fileset dir="${dist.dir}/dependencies/" includes="*/*/spring.handlers"/>
  </concat>
  <concat destfile="${dist.dir}/dependencies/META-INF/spring.schemas" fixlastline="true">
    <fileset dir="${dist.dir}/dependencies/" includes="*/*/spring.schemas"/>
  </concat>
  <concat destfile="${dist.dir}/dependencies/META-INF/spring.tooling" fixlastline="true">
    <fileset dir="${dist.dir}/dependencies/" includes="*/*/spring.tooling"/>
  </concat>
  <concat destfile="${dist.dir}/dependencies/META-INF/spring.factories" fixlastline="true">
    <fileset dir="${dist.dir}/dependencies/" includes="*/*/spring.factories"/>
  </concat>

  <!-- build the uber jar! -->
  <delete file="${dist.dir}/myproject-with-dependencies.jar" failonerror="false"/>
  <jar destfile="${dist.dir}/myproject-with-dependencies.jar">
    <!-- all dependency files except spring.* -->
    <fileset dir="${dist.dir}/dependencies/uber"/> 
    <!-- the spring.* files -->
    <fileset dir="${dist.dir}/dependencies/" includes="META-INF/*"/>
    <!-- my project's classes & etc -->
    <zipgroupfileset dir="${dist.dir}" includes="myproject.jar" />
    <manifest>
      <attribute name="Main-Class" value="${main.class}"/>
    </manifest>  
  </jar>
</target>


来源:https://stackoverflow.com/questions/23574979/creating-an-uber-jar-with-spring-dependencies

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!