programing tip

여러 병을 결합하는 깨끗한 방법?

itbloger 2020. 12. 3. 07:36
반응형

여러 병을 결합하는 깨끗한 방법? 가급적 Ant 사용


단일 jar로 "rejar"하려는 일부 외부 jar에 대한 런타임 종속성이 있습니다. 이러한 외부 종속성은 external_jars 디렉토리에 저장되며 모두 나열 할 필요가 없습니다 (즉, 종속성이 변경된 경우 빌드 스크립트를 변경할 필요가 없음). 이견있는 사람?

Google은이 작업을 수행하는 방법에 대한 좋은 답변을주었습니다. 각 항아리를 종속성으로 나열해도 괜찮다면 다음과 같습니다.

http://markmail.org/message/zijbwm46maxzzoo5

대략적으로, lib 디렉토리의 모든 jar를 out.jar로 결합하는 다음 줄을 따라 뭔가를 원합니다 (정상적인 덮어 쓰기 규칙 포함).

jar -combine -out out.jar -in lib/*.jar

zipgroupfilesetAnt Zip 작업 과 함께 사용 하십시오.

<zip destfile="out.jar">
    <zipgroupfileset dir="lib" includes="*.jar"/>
</zip>

이렇게하면 포함 된 모든 jar 라이브러리의 콘텐츠가 병합됩니다.


Vladimir의 대답은 정답이지만, 그가 제안한 것은 모든 항아리를 하나의 큰 out.jar에 다시 포장 한 다음 Ant Jar 작업에 단일 <zipfileset>또는 이와 유사한 것으로 공급한다는 것을 의미한다고 생각합니다. 이 2 단계 접근 방식은 필요하지 않습니다. 이것이 Ant 버전과 연결되어 있는지 확실하지 않지만 Ant 1.7.1이 있으며 해당 <jar>작업은을 이해 <zipgroupfileset>하여 타사 jar의 모든 내용을 직접 공급할 수 있습니다.

<jar destfile="MyApplication.jar">
  <zipgroupfileset dir="lib" includes="*.jar" /> 
  <!-- other options -->
  <manifest>
    <attribute name="Main-Class" value="Main.MainClass" />
  </manifest>
</jar>

jarjar를 확인할 수 있습니다.

http://code.google.com/p/jarjar/


먼저 마샬링 디렉토리에 JAR의 압축을 풉니 다.

<target name="combine-jars">
    <mkdir dir="${marshall.dir}"/>
    <unzip dest="${marshall.dir}">
        <fileset dir="${external.jar.dir}">
            <include name="**/*.jar"/>
        </fileset>
    </unzip>
    <jar destfile="${combined.jar}" basedir="${marshall.dir"}>
    <delete dir="${marshall.dir}"/>
</target>

어디에서 ${marshall.dir}임시 디렉토리이며, ${external.jar.dir}당신이 JAR의의를 유지하는 곳이며, ${combined.jar}대상 JAR이다.


maven을 사용한다면 왜 안할까요? :) 그냥 maven-shade-plugin을 사용하면 매력처럼 작동합니다!

  <project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>1.5</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <transformers>
                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                  <mainClass>com.YOUR_COMPANY.YOUR_MAIN_CLASS</mainClass>
                </transformer>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  ...
</project>

이것은 내 해결책입니다.

<target name="-post-jar">
    <echo>Packaging ${application.title} into a single JAR</echo>

    <jar destfile="${basedir}${file.separator}${dist.dir}${file.separator}_${ant.project.name}_.jar">
        <zipgroupfileset dir="${basedir}${file.separator}${dist.dir}" includes="${ant.project.name}.jar"/>
        <zipgroupfileset dir="${basedir}${file.separator}${dist.dir}${file.separator}lib" includes="*.jar"/>
        <manifest>
            <attribute name="Main-Class" value="${main.class}"/>
        </manifest>
    </jar>
</target>

Have you considered using Maven or some other system which manages your dependencies automatically? Then you would not need to specify where each library is located, what their names are, and what transitive dependencies your direct dependencies have. You would just state in one place what the dependency and its version are, and the system would take care of downloading the libraries, configuring the classpath and building the project.


The question is well answered. I wanted mention one tool I find useful - One-Jar. One-Jar handles resources more cleanly (by keeping all of them). This more useful if the code needs to process MANIFEST files.

Sample XML copied from website..

<import file="one-jar-ant-task.xml"/>   

    <target name="hello" depends="init">
        <!-- Build lib.jar -->   
        <javac destdir="${classes.dir}/lib">
            <src path="${lib.dir}" />
        </javac>
        <jar destfile="${build.dir}/lib.jar" >
            <fileset dir="${classes.dir}/lib"/>
        </jar>   
        <!-- Build classes for main.jar -->   
        <javac destdir="${classes.dir}/src">
            <src path="${src.dir}" />
            <classpath path="${build.dir}/lib.jar"/>   
        </javac>
        <!-- Construct the One-JAR file -->   
        <one-jar destfile="hello.jar" manifest="hello.mf">
            <main>
                <!-- Construct main.jar from classes and source code -->
                <fileset dir="${classes.dir}/src"/>
            </main>
            <lib>
                <fileset file="${build.dir}/lib.jar" />
            </lib>
        </one-jar>
        <echo>
          Now you can run the Hello One-JAR example using 
          $ java -jar hello.jar
        </echo>   

    </target>

If you are building with ant (I am using ant from eclipse), you can just add the extra jar files by saying to ant to add them... Not necessarily the best method if you have a project maintained by multiple people but it works for one person project and is easy.

for example my target that was building the .jar file was:

<jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
    <manifest>
        <attribute name="Author" value="ntg"/>
        ................................
        <attribute name="Plugin-Version" value="${version.entry.commit.revision}"/>
    </manifest>
</jar>

I just added one line to make it:

<jar ....">
    <zipgroupfileset dir="${external-lib-dir}" includes="*.jar"/>
    <manifest>
        ................................
    </manifest>
</jar>

where

<property name="external-lib-dir" value="C:\...\eclipseWorkspace\Filter\external\...\lib" />

was the dir with the external jars. And that's it... You can add multiple zipgroupfileset tags as well.


Well, I am not so much in to programming - but something simpler worked for me...if the question meant - combining jar files in to one. Ofcourse, this is manual, dirty solution. I just untarred all the tars...and then..created a new tar file, by adding all the directories formed by untarring- in to the new tar file. it worked.


Maven or other build tools can't "manage" the resolution of multiple versions of class files. In fact, Maven causes these problems in the first place, through transitive inclusion of all downstream jar files that are not explicitly required by a project.

Suppose somewhere in the transitive closure of a project (all libraries and modules required by the project, and all it's dependent projects, recursively) there are two versions of a class file. How could Maven possibly know which one is the 'correct' one? which one was intended by the programmer?

It can't because this information was lost when explicit dependencies were thrown away in favor of transitive ones (to save XML typing).

참고URL : https://stackoverflow.com/questions/515428/clean-way-to-combine-multiple-jars-preferably-using-ant

반응형