Strona używa cookies (ciasteczek). Dowiedz się więcej o celu ich używania i zmianach ustawień. Korzystając ze strony wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.    X

Przygotowanie programu Java dla Windows

W najprostszym przypadku aby uruchomić aplikację Java na systemie Windows wystarczy dwukrotnie kliknąć plik .jar, najczęściej wygenerowany podczas budowy naszego projektu w IDE (np. Eclipse, Netbeans, Intellij). Jednak gdy przygotowujemy aplikację dla osoby trzeciej, np. naszego klienta, może pojawić się kilka komplikacji / braków oczekiwanych udogodnień (zakładamy tutaj osobę o niewielkiej wiedzy informatycznej, nie administrstora-specjalistę):

  • Klient nie posiada zainstalowanego środowiska uruchomieniowego Javy (JRE) służącego do uruchamiania aplikacji .jar.
  • Klient posiada przestarzałą wersję JRE, niekompatybilną z naszym programem.
  • Program powinien mieć instalator, który umieści aplikację "gdzieś na komputerze", a Klientowi utworzy ikony do kliknięcia na pulpicie oraz w Menu Start.
W pierwszych dwóch przypadkach nasz program po prostu nie zadziała, przy braku instalatora nie będzie odbierany jako "profesjonalny".

Aby rozwiązać te 3 problemy użyjemy:

Tutorial wykorzystuje najnowsze wersje pakietów na chwilę obecną, w tym Javę 1.7, lecz opisane kroki (po zmienieniu numerów wersji w pliku pom.xml) powinny zadziałać też dla wersji 1.6 oraz prawdopodobnie najbliższych kolejnych wydań Javy.

Cała procedura została przeprowadzona na systemie Windows, ale kroki 1. i 2. z powodzeniem można wykonać na dowolnym systemie.

Krok 1. Przygotowanie przykładowej aplikacji

W swoim ulubionym IDE stwórz nowy projekt korzystajacy z Maven-a, utwórz w nim 2 klasy - App oraz MyFrame.package pl.com.radzikowski.developingforwindows; import java.awt.EventQueue; public class App { public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { new MyFrame(); } }); } } package pl.com.radzikowski.developingforwindows; import java.awt.Font; import java.awt.Label; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; public class MyFrame extends JFrame { MyFrame() { Font font = new Font("Verdana", Font.PLAIN, 18); Label label = new Label("Hello (cruel) Windows World!"); label.setFont(font); add(label); addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); pack(); setVisible(true); } }

Uaktualnij plik konfiguracyjny Mavena, podając informacje odnośnie projektu oraz używanej wersji Javy. Na tym etapie plik pom.xml powinien wyglądać jak poniżej.<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>pl.com.radzikowski.developingforwindows</groupId> <artifactId>JavaDevelopedForWindows</artifactId> <packaging>jar</packaging> <version>1.0</version> <name>JavaDevelopedForWindows</name> <url>http://radzikowski.com.pl</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.5.1</version> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> </plugins> </build> </project>

Krok 2. Stworzenie pliku .exe

Kolejnym etapem jest stworzenie pliku .exe uruchamiającego nasz program. Aby uniezależnić się od tego, czy nasz klient posiada zainstalowane środowisko JRE, dołączymy jego najnowszą wersję do naszego projektu. Przy uruchomieniu pliku .exe kolejne próby uruchomienia naszego programu będą wyglądały następująco:
  • Sprawdź, czy na komputerze zainstalowane jest JRE w wersji minimum 1.7. Jeżeli tak, użyj go do uruchomienia pliku .jar.
  • Sprawdź, czy w katalogu programu znajduje się folder z JRE w wersji minimum 1.7. Jeżeli tak, użyj go do uruchomienia pliku .jar.
  • Wyświetl komunikat o braku JRE, otwóz stronę pobierania środowiska w przeglądarce.
Za wszystko to odpowiadać będzie wtyczka launch4j.

Etap 2.1. Pobierz najnowszą wersję JRE

Ze strony http://www.oracle.com/technetwork/java/javase/downloads/jre7-downloads... pobierz paczkę dla Windows x86, w momencie tworzenia tego tutoriala najnowszą wersją jest jre-7u45-windows-i586.tar.gz.

Z paczki wypakuj (przy użyciu np. programu 7-Zip) katalog jre1.7.0_45, przenieś go do głównego katalogu projektu. Folder po wypakowaniu powinien ważyć 110 MB.

Etap 2.2. Dodaj wtyczki przygotowujące plik .exe

W pliku pom.xml dodaj kolejne 3 wtyczki w drzewie project -> build -> plugins.<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>2.6</version> <executions> <execution> <id>copy-resources</id> <phase>package</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/jre</outputDirectory> <resources> <resource> <directory>jre1.7.0_45</directory> </resource> </resources> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.2</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> <configuration> <shadedArtifactAttached>true</shadedArtifactAttached> <shadedClassifierName>shaded</shadedClassifierName> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>pl.com.radzikowski.developingforwindows.App</mainClass> </transformer> </transformers> </configuration> </plugin> <plugin> <groupId>com.akathist.maven.plugins.launch4j</groupId> <artifactId>launch4j-maven-plugin</artifactId> <version>1.5.1</version> <executions> <execution> <id>l4j-clui</id> <phase>package</phase> <goals> <goal>launch4j</goal> </goals> <configuration> <headerType>gui</headerType> <jar>${project.build.directory}/${project.artifactId}-${project.version}-shaded.jar</jar> <outfile>${project.build.directory}/JavaDevelopedForWindows.exe</outfile> <downloadUrl>http://java.com/download</downloadUrl> <classPath> <mainClass>pl.com.radzikowski.developingforwindows.App</mainClass> <preCp>anything</preCp> </classPath> <jre> <path>jre</path> <minVersion>1.7.0</minVersion> <jdkPreference>preferJre</jdkPreference> </jre> <versionInfo> <fileVersion>1.0.0.0</fileVersion> <txtFileVersion>${project.version}</txtFileVersion> <fileDescription>${project.name}</fileDescription> <copyright>2013 Maciej Radzikowski radzikowski.com.pl</copyright> <productVersion>1.0.0.0</productVersion> <txtProductVersion>1.0.0.0</txtProductVersion> <productName>${project.name}</productName> <companyName>Maciej Radzikowski</companyName> <internalName>JavaDevelopedForWindows</internalName> <originalFilename>JavaDevelopedForWindows.exe</originalFilename> </versionInfo> </configuration> </execution> </executions> </plugin>

Zadania poszczególnych wtyczek:

  • maven-resources-plugin - kopiuje katalog jre1.7.0_45 do target/jre.
  • maven-shade-plugin - przygotowuje wersję pliku .jar z dołączonymi zależnościami (dependencies - akurat nie ma ich w naszym bardzo prostym, przykładowym projekcie) możliwą do uruchomienia przez podwójne kliknięcie lub konsolowym poleceniem dzięki dołączeniu informacji o nazwie klasy głównej.
  • launch4j-maven-plugin - przygotowuje właściwy plik .exe uruchamiający plik .jar w środowisku określonym wg punktów z kroku 2.

Etap 2.3. Sprawdzenie działania programu

Będąc w katalogu projektu otwórz katalog target. Powinny się tam znajdować między innymi:
  • Katalog jre
  • Plik JavaDevelopedForWindows-1.0-shaded.jar
  • Plik JavaDevelopedForWindows.exe

Spróbuj uruchomić oba ostatnie pliki. W obu przypadkach powinno pojawić się okienko:

Uruchomienie pliku JavaDevelopedForWindows.exe powinno się udać także po:

  • Usunięciu katalogu jre z katalogu target
  • LUB odinstalowaniu środowisk JRE i JDK.
Natomiast po wykonaniu obu powyższych operacji próba uruchomienia programu powinna zakończyć się ukazaniem komunikatu oraz otwarciem strony http://java.com/download.

Krok 3. Stworzenie instalatora

Ostatnim etapem jest stworzenie instalatora. Użyjemy do tego programu Inno Setup. Alternatywą jest ISTool, który jest graficznym interfejsem dla Inno Setup, pomocnym przy tworzeniu bardziej wyszukanego instalatora.

Uruchom program Inno Setup, wybierz opcję "Create a new script file using the Script Wizard". Zatwierdź, kliknij "Next" w pierwszym kroku wizarda. Następnie podaj podstawowe dane programu, np.:

W kolejnym kroku wszystkie opcje pozostaw domyślne.

W następnym kroku należy podać pliki, które mają zostać zapakowane do instalatora, a następnie przy instalacji umieszczone w docelowym katalogu. Naszym głównym plikiem wykonywalnym będzie target/JavaDevelopedForWindows.exe z naszego projektu. Musimy także dołączyć katalog target/jre (z podkatalogami) oraz oczywiście plik JavaDevelopedForWindows-1.0-shaded.jar.

Opcje umieszczenia ikon programu możesz dobrać według własnego uznania i potrzeb.

Zgodnie z informacją w README JRE 7 przy jego redystrybucji musimy upewnić się, że użytkownik zaakceptuje jego licencję. Są na to dwa sposoby - albo dołączamy oryginalną treść licencji i wymagamy jej akceptacji w instalatorze, albo przygotowujemy własną licencję do produktu zawierającą odnośnik do licencji JRE w paragrafie o oprogramowaniu osób trzecich. Choć pewnie zazwyczaj będziemy używać tej drugiej opcji, tu na potrzeby naszego małego przykładu po prostu dołączymy licencję Oracle. Jak widzimy w pliku jre1.7.0_45/LICENSE, znajdziemy ją pod adresem http://java.com/license. Skopiuj ją do pliku .txt, a następnie dodaj w kolejnym oknie kreatora.

W kolejnym kroku warto wybrać język polski plus ew. inne jako języki instalatora. Dalej w opcjach instalatora możemy wybrać pulpit lub nasz projekt jako folder stworzenia pliku instalatora, oraz dostosować nazwę pliku. Jeżeli wizard zapyta nas o użycie dyrektyw #define, opcję tą można zostawić zaznaczoną dla zwiększenia czytelności późniejszego skryptu instalatora. Ostatnie co nam pozostało to zakończyć kreatora, zapisać skrypt konfiguracji i go skompilować.

Krok 4. Sprawdzenie działania instalatora

Ostatnim co nam zostało to uruchomić plik Java Developed For Windows Setup.exe i klikając Dalej zainstalować program, po czym go uruchomić - klikając ikonę na pulpicie lub w Menu Start.

Uwagi końcowe

Tutorial ten powstał po spędzeniu kilku dni na przemyśleniach i poszukiwaniach, w jaki sposób najlepiej przygotować program napisany w Javie dla klienta, który chce zainstalować go na Windowsie, a następnie zbieraniu wszystkich elementów w jeden projekt.

Można tu dywagować nad tym, czy tworzenie .exe nie przeczy idei wieloplatformowości Javy. Moim zdaniem - nie. Gdybym miał program okienkowy, który chciałbym upublicznić także dla mniej zaawansowanych użytkowników, umieściłbym go do pobrania w 2 wersjach - .jar i .exe taki jak powyższy. Użytkownicy Windowsa z zasady nie chcą się bawić w instalowanie dodatkowego oprogramowania, chcą mieć jak najprostszy sposób zainstalowania i używania programu. A w rzeczywistości program nadal uruchamia się w środowisku Javy. W ten sposób wszyscy zyskują naprawdę niewielkim nakładem pracy programisty.

Końcowy plik instalatora Java Developed For Windows Setup.exe dzięki spakowaniu naszego katalogu jre (który sam ważył 110 MB) ma 24.3 MB. Jest to lepszy wynik niż w przypadku uprzedniego skompresowania katalogu jre do .zip i dopiero wtedy dodaniu do instalatora, przynajmniej w moim przypadku. Wynik 24.3 MB uważam za bardzo dobry, ale można próbować dodatkowo go zmniejszyć:

 

windows porady programowanie

Komentarze

0 nowych
Frankfurterium   10 #1 15.12.2013 11:16

"Można tu dywagować nad tym, czy tworzenie .exe nie przeczy idei wieloplatformowości Javy. Moim zdaniem - nie."

Logika podpowiada, że jak najbardziej. To wręcz kastracja wszelkich znamion multiplatformowości. Zgoda, oczywiście, że nie każdemu multiplatformowość do szczęścia potrzebna, ale nie nazywajmy czarnego białym.

Mimo wszystko pytania o podobne sprawy często przewijają się przez rożne fora i przynajmniej będzie gdzie przekierowywać ludzi. Dobrych wpisów How-2-Java nigdy zbyt wiele.

mikolaj_s   14 #2 15.12.2013 13:09

A czy dołącznie jre do swojego programu jest legalne?
Nie rozglądałeś się za jakimś multiplatformowym instalatorem?

Radzikowski   3 #3 15.12.2013 13:13

Wiem, że to temat kontrowersyjny, i będzie tyle opinii za, jak i przeciw. Jednak tworząc oprogramowanie warto mieć na uwadze nie tylko szczytne idee (z którymi tu się jak najbardziej zgadzam), ale też potrzeby i wygodę klienta.
Dlatego jak pisałem - dzięki temu, że sama aplikacja jest napisana w Javie, stworzenie takiego instalatora może być dodatkiem zapewniającym wygodę, dystrybuowanym razem z czystym .jar.

Radzikowski   3 #4 15.12.2013 13:19

"A czy dołącznie jre do swojego programu jest legalne? " - tak, spójrz proszę na readme z przedostatniego linka - Oracle samo tłumaczy, jak redystrybuować JRE ze swoją aplikacją. Nielegalne jest tylko dołączanie wersji beta i pre-release.
"When you deploy an application written in the Java programming
language, your software bundle will probably consist of the following
parts:

Your own class, resource, and data files.
A runtime environment.
An installation procedure or program."
"NOTE - The license for this software does not allow the
redistribution of beta and other pre-release versions."

Teraz widzę tylko, że w instalatorze powinna być kopia licencji JRE i wymagana zgoda. W wolnej chwili poprawię tutorial.

Natomiast multiplatformowe instalatory - w zasadzie zrobią to samo, co my, tylko kosztują kilka tysięcy $. http://www.ej-technologies.com/buy/install4j/select, http://www.advancedinstaller.com/purchase.html

TestamenT   12 #5 15.12.2013 14:22

@mikolaj_s widziałem gry na Steam napisane w jawie (ble) gdzie jre znajdowało się już rozpakowane w folderze z grą. Ale czy licencja tego zabrania, ja nie wiem. Ale z wyrocznią nigdy nic nie wiadomo.

Frankfurterium   10 #6 15.12.2013 14:52

@mikolaj_s

FAQ Oracla:

Q: "Can I distribute Java with my software?"
A: "Yes, you can provide Java with your software provided you abide by the terms and conditions of Java binary code license."

  #7 15.12.2013 18:37

Jave wymyślili kosmici żeby dręczyć biednych programistów i bezproduktywnie konsumować zasoby ziemi i zmuszać użytkowników do zakupu RAM, inni kosmici wymyślili QT żeby dręczyć użytkowników i zmuszać do zakupu dysku SSD ale programiści byli zadowoleni więc dręczą użytkowników, a jeszcze inni wymyślili inline assembly AT&T w GCC żeby odstraszać programistów od asemblerowych wstawek i zmuszać do pisania C, jeszcze inni kosmici próbowali odstraszyć autora wpisu od jego napisania żeby nie utrudniał dręczenia przydatnymi tutorialami!

Jedno pytanie za każdym razem widzac osobe z windows 8
jest oczywiście legalny - prawda?
zastanawiające bo skoro windows jest tak popularny a Visual Studio wygodne i tworzy natywny kod to po co komu Java?
odpowiedź prosta - żeby dręczyć biednych ludzi!

mikolaj_s   14 #8 15.12.2013 21:53

Możliwość dołączenia jre jest super, to miło ze strony Oracle :-)

@Radzikowski: No raczej musiałbym mieć specjalny powód aby kupować narzędzie dla instalatora, no i pewnie w takim wypadku dla Linuksa napisałbym zwykły skrypt uruchamiający apta/yuma do instalacji openjdk.

@_int64: Dobry, żart :-) Pisz wszystko w assemblerze i nie męcz użytkowników. A dla aplikacji pisanych na zlecenie, a nie masowego użytku Java jest idealna, .NET też niezły ale nie multiplatformowy, mało kto tworzy takie aplikacje natywnie, czas to pieniądz.

Radzikowski   3 #9 15.12.2013 22:31

@__int64 owszem, Windows jest legalny, dołączony do komputera. Poza tym jako student mam także możliwość pobrania go z Dreamsparka. Nie zmienia to faktu, że wchodzę na niego tylko w jednym celu - pograć w gry. Na co dzień programuję na Linuxie, a osobiście Visual Studio (także mam możliwość pobrania z Dreamsparka) nie lubię.
Poza tym, tak jak pisze @mikolaj_s, oczywiście powinniśmy wszystko pisać w assemblerze. Najwydajniej, bez grama niepotrzebnego kodu dodanego przez pośredniczące kompilatory. Tylko myślę, że bez wysokopoziomowych języków programowania nie korzystałbyś teraz tak swobodnie z komputera czy internetu.

@mikolaj_s Dla Linuxa napisałbym skrypt w jednej linijce - "java -jar program.jar", albo i nawet tego bym nie robił. Na wielu dystrybucjach openJDK jest domyślnie, na pozostałych użytkownicy sami wiedzą, że należy ją zainstalować do obsługi formatu .jar.

Frankfurterium   10 #10 15.12.2013 22:32

@mikolaj_s

Skrypt uruchamiający managera pakietów to nawet krok dalej niż wyzbycie się multiplatforowości. Kiedyś dało się zrobić taki myk, żeby pobrać JRE/JDK prosto od Oracle'a. Zwykłe połączenie wgetem ze sfabrykowanym cookie. A jeszcze lepiej zwyczajnie uwzględnić w wymaganiach programu obecność JRE minimum którejś wersji.

GL1zdA   12 #11 16.12.2013 07:43

Nie przesadzajmy z tym wyzbyciem się multiplatformowości. Przecież nie musisz dystrybuować tylko jednej paczki instalacyjnej. Możesz mieć prosty instalator dla Windows i zwykłe archiwum, dla tych co wolą taką wersję.

mikolaj_s   14 #12 16.12.2013 17:36

@Radzikowski: Dlaczego zakładasz, że każdy użytkownik Linuksa sam sobie poradzi, a z użytkownika Windowsa robisz lenia lub głupola? IMHO w taki sposób utrwalane się przekonania, że Linuks jest tylko dla geeków.

@Frankfurterium: Przecież i tak instalator musi się różnić dla każdego systemu. Widziałem już takie instalatory, uruchaniające JVM z graficznym instalatorem w Swingu, a wcześniej przy jej braku ściągające jre. Jedynie miłoby mieć takie narzędzie, które wygenerowłoby skrypty nie tylko dla Windows.

Frankfurterium   10 #13 16.12.2013 18:17

@mikolaj_s

Teraz nie za bardzo wiem, o czym piszesz. Konieczność posiadania osobnego instalatora na różne systemy - w sumie trzech - ma usprawiedliwiać tworzenie osobnych skryptów dla każdej dystrybucji (bo mimo tego samego managera, pakiety w repozytorium mogą już nazywać się inaczej) - w sumie... dużo?

mikolaj_s   14 #14 16.12.2013 23:34

@Frankfurterium: Pewnie byłoby lepiej zrobić paczki, to bardziej oczekiwane rozwiązanie przez użytkowników Linuksa. Natomiast jeśli pisać skrypt instlacyjny to dla określonych dystrybucji, tych najpopularniejszych. Ja się rozmarzyłem nad posiadaniem narzędzia, które ułatwiałoby tworzenie takich instalatorów, bo jeden instalator na różne systemy jest nierealny, ale na różne dystrybuje Linuksa już się da zrobić.

  #15 03.07.2015 16:17

Ehhh...

  #16 12.09.2015 15:51

Czy jest jakieś rozwiązanie aby projekt stworzony bez mavena "skompilować" w ten sposób