NetBeans - развертывание всего в одной банке

Возможный дубликат:
Поставить внешнюю библиотеку в JAR?

У меня есть NetBeans 6.8, и я написал один класс, который имеет две библиотеки (jar-файлы). Создавая его, я получаю папку "dist" с моим project.jar и папку "lib", которая содержит два файла lib jar.

Как я могу получить все это в одном файле JAR? (Я не использую Maven/Ant или что-то подобное.)

5 ответов

Решение

Основная проблема заключается в том, что текущая версия Java не поддерживает jar-файлы внутри jar-ов из коробки.

Рекомендуемое решение - использовать строку Class-Path в файле MANIFEST.MF внутри вашего jar-файла, чтобы указать на необходимые библиотеки (допустимы относительные пути), а затем развернуть все файлы вместе и вызвать ее с помощью "java -jar your.jar".

Если вы действительно хотите иметь решение "jar-inside-jar", мы использовали один jar в течение нескольких лет, но отказались от него, поскольку наша целевая JVM работала лучше с решением, описанным выше.

http://one-jar.sourceforge.net/

Я использовал его с плагином Fatjar в Eclipse. У меня нет опыта встраивания его в Netbeans, но его просто встроить в сценарий ant, который, как мне кажется, в любом случае используют NEtbeans.

Вы можете создать дополнительную цель сборки в файле build.xml. И использовать zipfileset а также zipgroupfileset создать одну большую банку, например

<target name="YourBigJar" depends="-post-jar">
  <jar destfile="BigJar.jar">
    <zipfileset src="dist/Project1.jar"/>
    <zipfileset src="../OtherProject/dist/project2.jar"/>
    <zipgroupfileset dir="../libs/."/>
  </jar>
</target>

Я согласен с Waverick. Самый простой способ сделать это с помощью NetBeans - добавить пользовательскую цель в ваш build.xml. (Кстати, благодаря использованию NetBeans вы используете Ant, поскольку NetBeans использует Ant для создания вашего jar-файла.)

Похоже, цель Waverick Ant предназначена для объединения скомпилированного кода из другого проекта NetBeans в файл JAR текущего проекта. Мои цели ниже делают именно то, что вы ищете.

<target name="-unjar-and-copy-lib-jars">
    <unjar dest="${build.classes.dir}">
        <fileset dir="lib">
            <include name="**/*.jar"/>
        </fileset>
        <patternset>
            <exclude name="META-INF/**"/>
            <exclude name="/*"/>
        </patternset>
    </unjar>
</target>

<target depends="init,compile,-pre-pre-jar,-pre-jar,-unjar-and-copy-lib-jars" name="fat-jar">
    <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
    <jar destfile="${dist.jar}">
        <fileset dir="${build.classes.dir}"/>
        <manifest>
            <attribute name="Main-Class" value="${main.class}"/>
        </manifest>
    </jar>
    <echo>To run this application from the command line without Ant, try:</echo>
    <property location="${dist.jar}" name="dist.jar.resolved"/>
    <echo>java -jar "${dist.jar.resolved}"</echo>
</target>

<target depends="clean,fat-jar" name="clean-and-fat-jar"/>

Я нашел хорошую статью здесь. Но, похоже, стоит упомянуть, что это запрос внешних библиотек в папке dest/lib. Вы можете сделать это таким образом, но обычно у нас есть папка lib в корневой папке (или что у меня есть). Если это просто изменить

<zipgroupfileset dir="dist/lib" includes="*.jar"/> в

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

Это все.

Вы можете использовать Java для установки внешних библиотек программно, используя Class.getResourceAsStream() и FileOutputStream, Библиотеки обычно идут в Java\lib\ext\,

Вот как я подошел к этому:

Я поместил копию всех банок, которые я использовал в .res подпакет. Оттуда я могу скопировать их куда угодно.

private void installLibraries() {
    new Thread() {

        @Override
        public void run() {
            System.out.println("Checking for libraries");

            File jre = new File(System.getProperty("java.home"));
            File jar = new File(jre, "lib/ext/JAR_NAME.jar");
            //Create more File objects that wrap your JAR's
            try {
                boolean added = false;

                if (!jar.exists()) {
                    copyResource(jar, "JAR_NAME.jar");
                    added = true;
                }
                //Repeat for more JAR's

                if (added) {
                    System.out.println("Libraries installed.");
                } else {
                    System.out.println("Library check complete");

            } catch (IOException ex) {
                System.out.println("Library installation failed.");
                ex.printStackTrace(System.out);
            }
        }

        private void copyResource(File dest, String src) throws IOException {
            System.out.println("Copying resource " + src + " to " + dest);
            InputStream in = THIS_CLASS_NAME.class.getResourceAsStream("/YOUR_PACKAGE/res/" + src);
            dest.getParentFile().mkdirs();
            FileOutputStream out = new FileOutputStream(dest);
            byte[] buffer = new byte[1024];
            int i = 0;
            while ((i = in.read(buffer)) > 0) {
                out.write(buffer, 0, i);
            }
            out.close();
            in.close();
        }
    }.start();
}

Запустите этот метод, прежде чем делать что-либо еще, и вы можете полностью игнорировать внешние файлы JAR, которые вам дает Netbeans, и просто распространять один. Как дополнительное примечание, я использовал этот метод для установки javax.comm, который не любил распространяться извне. Он поставляется с файлом.dll и файлом свойств. Эти файлы могут быть установлены точно таким же способом, но стоит отметить, что файл.dll должен быть помещен в Java\lib\ каталог и файлы свойств идут в Java\lib\ каталог (не в \ext папка).

Другие вопросы по тегам