Java Tip 127: Вижте JAR run

Можете лесно да опаковате целия набор от класове и ресурси на приложение в Java Archive (JAR). Всъщност това е една от целите да имате jar файлове. Друго е да позволите на потребителите лесно да изпълняват приложението, съхранявано в архива. Защо тогава jar файловете са второкласни граждани във вселената на Java - функционират само като архиви - когато те могат да бъдат първокласни, точно до родните изпълними файлове?

За да изпълните jar файл, можете да използвате

java

команда

-jar

опция. Например, да речем, че имате наречен изпълним jar файл

myjar.jar

. Тъй като файлът може да се изпълнява, можете да го изпълните по следния начин:

java -jar myjar.jar

.

Като алтернатива, Java Runtime Environment (JRE), когато е инсталирана на операционна система като Microsoft Windows, свързва jar файлове с JVM, за да можете да щракнете двукратно върху тях, за да стартирате приложението. Тези JAR трябва да могат да се изпълняват.

Въпросът е: Как да направите JAR изпълним?

Файлът на манифеста и записа от основния клас

В повечето JAR файлове се нарича файл

MANIFEST.MF

се съхранява в директория, наречена

META-INF

. Вътре в този файл се нарича специален запис

Main-Class

казва на

java -jar

команда кой клас да се изпълни.

Проблемът е, че трябва да добавите правилно този специален запис към файла на манифеста - той трябва да отиде на определено място и да има определен формат. Някои от нас обаче не обичат редактирането на конфигурационни файлове.

Нека API го направи вместо вас

От Java 1.2, наречен пакет java.util.jarви позволява да работите с jar файлове. (Забележка: Той се основава на java.util.zipпакета.) По-конкретно, пакетът jar ви позволява лесно да манипулирате този специален файл на манифеста чрез Manifestкласа.

Нека напишем програма, която използва този API. Първо, тази програма трябва да знае за три неща:

  1. JAR, който искаме да направим управляем
  2. Основният клас, който искаме да изпълним (този клас трябва да съществува в JAR)
  3. Името на нов JAR за нашия изход, защото не трябва просто да презаписваме файлове

Напишете програмата

Горният списък ще представлява аргументите на нашата програма. На този етап нека изберете подходящо име за това приложение. Как MakeJarRunnableзвучи?

Проверете аргументите на main

Да приемем, че основната ни входна точка е стандартен main(String[])метод. Първо трябва да проверим програмните аргументи тук:

if (args.length! = 3) {System.out.println ("Usage: MakeJarRunnable" + ""); System.exit (0); }

Моля, обърнете внимание на това как се тълкува списъкът с аргументи, тъй като е важен за следния код. Редът и съдържанието на аргументите не са зададени в камък; обаче, не забравяйте да модифицирате другия код по подходящ начин, ако ги промените.

Достъп до JAR и неговия файл с манифести

Първо, трябва да създадем някои обекти, които знаят за JAR и манифестните файлове:

// Създаване на обект JarInputStream и получаване на неговия манифест JarInputStream jarIn = нов JarInputStream (нов FileInputStream (аргументи [0])); Манифест манифест = jarIn.getManifest (); if (manifest == null) {// Това ще се случи, ако не съществува манифест manifest = new Manifest (); }

Задайте атрибута Main-Class

Поставяме Main-Classзаписа в раздела за основните атрибути на файла на манифеста. След като получим този набор от атрибути от манифестния обект, можем да зададем подходящия основен клас. Какво обаче, ако Main-Classатрибут вече съществува в оригиналния JAR? Тази програма просто отпечатва предупреждение и излиза. Може би бихме могли да добавим аргумент от командния ред, който казва на програмата да използва новата стойност вместо предишната:

Атрибути a = manifest.getMainAttributes (); Низ oldMainClass = a.putValue ("Основен клас", аргументи [1]); // Ако съществува стара стойност, кажете на потребителя и излезте, ако (oldMainClass! = Null) {System.out.println ("Предупреждение: старата стойност на Main-Class е:" + oldMainClass); System.exit (1); }

Изведете новия JAR

Трябва да създадем нов jar файл, така че трябва да използваме JarOutputStreamкласа. Забележка: Трябва да се уверим, че не използваме същия файл за изход, както за вход. Като алтернатива, може би програмата трябва да разгледа случая, когато двата файла с jar са еднакви и да подкани потребителя, ако желае да презапише оригинала. Въпреки това си запазвам това като упражнение за читателя. Продължете с кода!

 System.out.println("Writing to " + args[2] + "..."); JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(args[2]), manifest); 

We must write every entry from the input JAR to the output JAR, so iterate over the entries:

 //Create a read buffer to transfer data from the input byte[] buf = new byte[4096]; //Iterate the entries JarEntry entry; while ((entry = jarIn.getNextJarEntry()) != null) { //Exclude the manifest file from the old JAR if ("META-INF/MANIFEST.MF".equals(entry.getName())) continue; //Write the entry to the output JAR jarOut.putNextEntry(entry); int read; while ((read = jarIn.read(buf)) != -1) { jarOut.write(buf, 0, read); } jarOut.closeEntry(); } //Flush and close all the streams jarOut.flush(); jarOut.close(); jarIn.close(); 

Complete program

Of course, we must place this code inside a main method, inside a class, and with a suitable set of import statements. The Resources section provides the complete program.

Usage example

Let's put this program to use with an example. Suppose you have an application whose main entry point is in a class called HelloRunnableWorld. (This is the full class name.) Also assume that you've created a JAR called myjar.jar, containing the entire application. Run MakeJarRunnable on this jar file like so:

 java MakeJarRunnable myjar.jar HelloRunnableWorld myjar_r.jar 

Again, as mentioned earlier, notice how I order the argument list. If you forget the order, just run this program with no arguments and it will respond with a usage message.

Try to run the

java -jar

command on

myjar.jar

and then on

myjar_r.jar

. Note the difference! After you've done that, explore the manifest files (

META-INF/MANIFEST.MF

) in each JAR. (You can find both JARs in the

source code

.)

Here's a suggestion: Try to make the MakeJarRunnable program into a runnable JAR!

Run with it

Running a JAR by double-clicking it or using a simple command is always more convenient than having to include it in your classpath and running a specific main class. To help you do this, the JAR specification provides a Main-Class attribute for the JAR's manifest file. The program I present here lets you utilize Java's JAR API to easily manipulate this attribute and make your JARs runnable.

Понастоящем Шон Силвърман е аспирант в катедрата по електротехника и компютърно инженерство в университета в Манитоба, Канада. Започва да работи с Java в средата на 1996 г. и оттогава я използва почти изключително. Текущите му интереси включват симулация на електрически полета и флуиди, кодове за коригиране на грешки и прилагане на изящни трикове с графичен потребителски интерфейс (графичен потребителски интерфейс). Шон също преподава трета година курс по софтуерен дизайн в отдела за компютърно инженерство в университета си.

Научете повече за тази тема

  • Изтеглете изходния код и JAR за този съвет

    //images.techhive.com/downloads/idge/imported/article/jvw/2002/05/makejarrunnable.zip

  • „Java Tip 120Execute Self-Extracting JARs“, Z. Steve Jin и John D. Mitchell ( JavaWorld, ноември 2001 г.)

    //www.javaworld.com/javaworld/javatips/jw-javatip120.html

  • JAR File Specification

    //java.sun.com/j2se/1.3/docs/guide/jar/jar.html

  • jar—The Java Archive Tool

    //java.sun.com/j2se/1.3/docs/tooldocs/win32/jar.html

  • View all previous Java Tips and submit your own

    //www.javaworld.com/javatips/jw-javatips.index.html

  • Learn Java from the ground up in JavaWorld's Java 101 column

    //www.javaworld.com/javaworld/topicalindex/jw-ti-java101.html

  • Java experts answer your toughest Java questions in JavaWorld's Java Q&A column

    //www.javaworld.com/javaworld/javaqa/javaqa-index.html

  • Browse the Core Java section of JavaWorld's Topical Index

    //www.javaworld.com/channel_content/jw-core-index.shtml

  • Бъдете в крак с нашите трикове N Tips, като се абонирате за безплатните седмични бюлетини на JavaWorld

    //www.javaworld.com/subscribe

  • Научете основните положения в страната на клиента Java в JavaWorld " и Java за начинаещи дискусия. Основните теми включват езика Java, виртуалната машина Java, API и инструменти за разработка

    //forums.idg.net/[email protected]@.ee6b804

  • Ще намерите изобилие от свързани с ИТ статии от нашите сестрински публикации в .net

Тази история, „Java Tip 127: Вижте изпълнение на JAR“, първоначално е публикувана от JavaWorld.