# Java - Updater



## Sephrox (4. Dez 2012)

Hey Leute,

ich wollte einen Updater mit Java schreiben.

Ich habe ein Chat Programm geschrieben das als Client und Server vorhanden ist um mit
anderen zu kommunizieren.
Nun habe ich für den Login-Frame meines ChatProgramms (über MySQL) einen Updater geschrieben.
Ich habe nun schon gelesen das man ein Nebenprogramm schreibt (Loader) und dann das Hauptprogramm (Login) mit nachfolgendem ChatFenster startet. Ein anderer Weg soll der direkte
Zugriff über die Runtime mit java -jar update blalba.jar sein. Nun sind bei mir bei beiden Verfahren
Fragen aufgetreten.

Ich packe mein Login Programm als Runnable Jar File damit man, wenn man auf Chatblabla.jar drückt
direkt das Programm startet (.exe Imitat bei Windows). So wenn ich jetzt einen Loader vorhängen würde, müsste ich ja die Runnable Jar chatblabla.jar überschreiben, dass ja so einfach nicht geht während diese läuft. Also das selbe Problem bleibt bestehen. 
Die 2. Variante verstehe ich nicht. Ich habe diese bei DreaminCode (Creating An Updater In Java - Java Tutorials | Dream.In.Code) 
gefunden unter Java Updater tutorial.
Heißt der Befehl, dass ich die laufende jar überschreiben kann oder wie funktioniert dies?

Habt ihr vllt einfachere Varianten?

Grüße und danke für Hilfe,

Sephrox


----------



## trääät (4. Dez 2012)

es gibt verschiedene ansätze sein programm-code upzudaten ... jedoch sollte man mindestens eine bereits implementieren BEVOR man sein programm verteilt ... ansonsten muss nachträglich vom user selbst gepatcht werden ...


ich denke sehr verbreitet sind launcher / loader / what ever man sie nennen möchte ...
ich selbst verwende bei meinen projekten auch einne der dafür zuständig ist den haupt-code sowie alle module zu checken und auf den neuesten stand zubringen bevor das haupt-system gestartet wird ...
allerdings besitzt mein launcher im gegensatz zu vielen anderen auch die fähigkeit sich selbst upzudaten ... das findet man so eher seltener ...

dann gibt es noch die variante den code des launcher quasi in die haupt-app mit reinzupacken ... also beim start gucken ob man selbst aktuell ist , wenn nicht > patchen und dann im restlichen verlauf ob alle programm-module aktuell sind ...
die idee ist die gleiche wie die erste ... jedoch verschweigt man den launcher-code in dem man alles in ein file packt

zusätzlich würden mir noch manuelle-patcher einfallen ... in dem sinne nur ein überschreiben der programm-daten während das programm selbst nicht aktiv ist ... ob man dies nun selbst macht oder ein tool schreibt kommt auf die komplexität an ...


grundsätzlich gilt aber : der launcher selbst ... also das jar was zu erst gestartet wird kann sich so selbst nur updaten in dem es temporär ein zweites von sich unabhängiges self-patcher-programm startet , sich selbst terminiert ... und durch den patcher die neue version gestartet wird ...


----------



## FArt (4. Dez 2012)

Java Webstart?


----------



## Guybrush Threepwood (5. Dez 2012)

Ein großes Problem bei dem von Dir geposteten Link besteht darin, dass es dann nicht funktioniert, wenn das Programm an einem geschützten Ort liegt. Bei Windows wäre das z. B. im Programme-Verzeichnis der Fall und der Updater müsste mit "elevated rights" laufen. Bei Mac OS X ist es ähnlich, wobei ich nicht weiß, wie ein Programm die Rechte zum Ändern von Dateien im Programm-Verzeichnis bekommen kann.


----------



## trääät (5. Dez 2012)

das problem hat man mit jeder software unter jedem system ...

... nur ist unix so aufgebaut das entweder alles in ordnern landet auf die man auch zugriff hat (meist user.home) oder man für system-weite änderungen root-rechte braucht ...

... unter windows ist eigentlich alles außer user.home blockiert ... und desshalb holen sich alle programme grundsätzlich über UAC admin-rechte ... womit sowohl UAC sinnfrei wird als auch das rechte-system von NTFS ... aber darüber wurde bereits an anderer stelle diskutiert ...

... um also das problem fehlender rechte zu umgehen sollte man als bewusster programmierer immer pfad wählen auf die der user schreibrechte hat ... und das ist nun mal user.home und alles was da drin liegt ...

anmerkungen zum gelinkten : also persönlich finde ich das was dort gemacht wird nicht grade so mega pernös ... denn es werden viele anfänger-fehler begangen wie [c]extends JFrame[/c] oder das man sich drauf verlässt das man als admin auch immer alle seiten aktuell hält ...
hier hätte man noch eine kleine engine in PHP dahinter setzen können die das ganze mit ner datenbank und ner kleinen admin-seite verbindet ...

am besten wäre eh immer ein eigener hoste mit eigener server-software ... so kann man client und server passend zu ein ander bauen ... natürlich verliert man etwas bequemlichkeit da man z.b. kein HTTP nutzen kann ... was aber egal ist wenn man über die streams eh direkt die binär-daten sendet ...

ich würde dir gern etwas code zur verfügung stellen ... doch leider ist mein system mit nem datenträgercrash vor einiger zeit verloren gegangen ... und ich müsste es auch erstmal selbst wieder implementieren und ausprobieren ...


----------



## Guybrush Threepwood (5. Dez 2012)

trääät hat gesagt.:


> das problem hat man mit jeder software unter jedem system ...
> 
> ... nur ist unix so aufgebaut das entweder alles in ordnern landet auf die man auch zugriff hat (meist user.home) oder man für system-weite änderungen root-rechte braucht ...
> 
> ...



Auf Mehrbenutzersystemen nicht unbedingt sooo schlau. Wäre auch ziemlich grässlich, wenn alle Programme sich in user.home installieren würden. Man denke nur einmal an große Office-Pakete etc. oder eben Software, die in verschiedenen Nutzerkonten verfügbar sein sollte.


----------



## TryToHelp (5. Dez 2012)

Dem schließe ich mich an, in das home Verzeichnes gehören Persönliche Daten, aber nicht Programme, also persönliche Config, gespeicherte Dokumente, Spielstände was auch immer, der Rest aber nicht.


----------



## FArt (5. Dez 2012)

TryToHelp hat gesagt.:


> Dem schließe ich mich an, in das home Verzeichnes gehören Persönliche Daten, aber nicht Programme, also persönliche Config, gespeicherte Dokumente, Spielstände was auch immer, der Rest aber nicht.



Warum sind Programme was besonderes? Wenn sie benutzerbezogen installiert werden, gehören sie in ein persönliches Verzeichnis. Das Home-Verzeichnis des Benutzers wäre hier ein guter Ausgangspunkt, z.B. <userhome>/applications/


----------



## TryToHelp (5. Dez 2012)

Wenn ich mir Windows anschaue (vorallem mal XP, da passt es von der Namung erst recht toll) gibt es einen Ordner namens Programme. In diesem erwarte ich das die Programme liegen und nicht in irgendwelchen anderen Verzeichnissen, außer ich gebe sie explizied an, wie einen selbsterstellten Ordner Games oder so, ansonsten ist das genau der richtige Ordner. Dan gibt es das homeverzeichnis, was damals Dokumente und Einstellungen hieß, was finde ich eine sehr passende bezeichnung ist, für das, was meiner Meinung nach da auch hin gehört, nämlich Dokumente, Speicherstände (was ja eine art spezieller Dokumente sind, Einstellungen ;-)


----------



## FArt (5. Dez 2012)

TryToHelp hat gesagt.:


> Wenn ich mir Windows anschaue



Kein gutes Beispiel... 

Wenn du dich fragst, wie es richtig gemacht werden sollte, kannst du zwar nachsehen, wie es andere machen, aber das solltest du auch hinterfragen. Gerade Windows ist da absolut kein gutes Beispiel.

Ich erwarte, dass alles, was nur mich als Benutzer etwas angeht in einem Bereich liegt, der nur von mir zugegriffen werden kann. Das gilt auch für Programme. Das persönliche Verzeichnis wäre somit ein denkbarer Ansatz. Dabei geht es mir nicht nur um Zugriffschutz, sondern auch um Sichtbarkeit.

Global installierte Programme dürfen gerne unter Applications liegen und von allen benutzt werden. Sinnvoll ist es dann, wenn diese Programme ihre Konfigurationen wiederum benutzerspezifisch ablegen.


----------



## Sephrox (5. Dez 2012)

Hey Leute, 
danke für die vielen Antworten doch ich glaube wir driften vom eigentlichen Thema ab... 
Also noch einmal Ausgangssituation....
Ich habe ein Serverprogramm der die Version bereitstellt und die neue Version der .jar Datei
Das Serverprogramm läuft als .jar auf meinem Server und kann per Client angesteuert werden.
Der Server regelt die Loginanfragen und auch die Versionsanfragen.
Sobald also die Version unterschiedlich ist sollte der Download beginnen.

Nun habe ich ja meinen Client der bereits die Funktion hat ein Update zu machen.
Mein Problem besteht darin, dass ich wärend das Programm läuft dieses ja nicht ersetzen kann.
(Klicke auf Chat.jar => Loginfenster öffnet sich => Update verfügbar button anklicken => Download fertig => Ersetze die aktuelle Chat.jar durch die neuere)
Und da liegt mein Problem. Die Loader Methode kann ich in diesem Fall meines Wissens auch nicht 
benutzen, da diese ja ebenfalls in der .jar Datei gepackt sein würde.... ich müsste praktisch nur
die aktuell laufende Jahr abschießen und diese neu starten, da die Datei ja dann ersetzt wird.
Aber wie ersetzt man eine Datei, die man während des laufens nicht ersetzen kann und nachdem 
man den Prozess beendet hat kein Code mehr ausgeführt wird?

Wenn ich 2 .jar hätte die eine als loader die andere als program könnte ich das hauptprogramm natürlich ersetzen wärend der Loader läuft... aber ich möchte ja nur eine ausführbare Datei auf dem desktop haben....


----------



## freez (5. Dez 2012)

Der Speicherort einer Anwendung hängt doch ganz von der Anwendung und dem User ab, der sie nutzt. Es gibt nun mal auch User welche eingeschränkte Rechte haben und trotzdem mit Ihren Rechten eine Anwendung aktualisieren sollen (Weil es vielleicht häufige Aktualisierungen gibt, extrem unterschiedliche Systeme gibt, der Admin keine Zeit hat, oder es keinen Admin gibt). Außerdem kann es durchaus sein, dass andere User des Systems keinen Zugriff auf diese Anwendung haben sollen.

Ich gebe zu, dass es ein recht selten anzutreffender Anwendungsfall ist. Aber die Alternativen dazu sind meist kompliziert/aufwendig (Mehraufwand in der Entwicklung), nicht sinnvoll (z.B. Update Service für Windows / Linux etc.) oder bedeuten, dass man das System rechtemäßig aufbohren muss. Dem gegenüber ist ein kleines Progrämmchen im Userordner die sinnvollere Variante.

Ein schönes Beispiel ist ja Java Webstart. Genaugenommen sind das Anwendungen, die nur dem User zur Verfügung gestellt und ohne Adminrechte "installiert" und geupdatet werden können. Und wo speichert Webstart seine "Installationsdateien"? Im User Ordner.


----------



## freez (5. Dez 2012)

Ich hatte mal einen ähnlichen Fall wo java webstart nicht in Frage kam (allerdings solltest du unbedingt den Einsatz prüfen. Webstart nimmt dir enorm Entwicklungsaufwand ab.)

Ich möchte es so empfehlen:
als beispiel: du hast 2 jars. programm.jar und updater.jar
1. Dein Programm.jar enthält dein eigentliches Programm. 
2. Deine Anwendungsverknüpfung startet eine main in updater.jar und diese prüft auf dem Server nach einer neueren Version von programm.jar
3. gibt es eine neue Version wird die programm.jar überschrieben
4. updater.jar startet per runtime.exec() die main aus deiner programm.jar. Hier sollte nach dem Start die Updater.jar sich beenden

Das schöne ist, du könntest von programm.jar aus die updater.jar updaten.

Sowas geht allerdings nur, wenn der User entweder Admin Rechte hat, oder die Jars im User.Home liegen.


----------



## FArt (5. Dez 2012)

Sephrox hat gesagt.:


> danke für die vielen Antworten doch ich glaube wir driften vom eigentlichen Thema ab...


Bedingt. Liegt auch daran, dass du auf konkrete Anregungen zu einer Lösung bisher nicht eingegangen bist. Webstart ist das eine, träääät hat auch schon einiges von sich gegeben...

Noch mal? Warum selber machen, wenn es Java Webstart gibt?

Zumindest könntest du dein Bootstrap-Jar über Webstart benutzen.

Dein Bootstrap muss möglichst stabil sein. Dann kann es dein Nutzprogramm regelmäßig updaten. Wenn das Bootstrap getauscht werden muss (selten!), kommt halt ein Dialog, dass der User noch mal aufs Knöpfchen drücken muss... kommt nicht so selten vor. Im Beenden einen Prozess forken, der die magische Arbeit übernimmt (ist eigentlich nur unter Windows nötig).

... aber... ich würde so weit es geht mit Webstart arbeiten... es muss sehr, sehr gute Gründe geben, so was selber zu klöppeln...


----------



## Sephrox (5. Dez 2012)

Hey,

ich möchte grundsätzlich etwas eigenes programmieren, wozu webstart nicht zählen würde.
Natürlich wäre es einfacher und ja ich werde es warscheinlich auch mal ausprobieren aber mir
geht es ums Verständnis. Es geht mir auch darum immer neue Wege kennen zu lernen und auszuprobieren und da hilft mir kein Weg der für mich schon vorbestimmt ist. Ich möchte verstehen
wieso etwas nicht funktioniert oder wie es anders funktionieren könnte. Ich könnte z.B. auch ein fertig gelösten Chat nutzen aber was würde mir das bringen?

2 jars auf dem Desktop zu haben würde ich wie gesagt ablehnen, da ein Programm ja meist nur aus einer Startdatei besteht. (wenn man von unterordnern configs ect ... absieht, die normalerweise bei größeren Anwendungen genutzt werden)
Man könnte ja theoretisch die beiden jars in eine hauptjar stecken aber wie das dann funktioniert
interessiert mich. Also die Programm.jar enthält z.b. Loader / Updater.jar und die Hauptprogramm.jar
aber es ist schwierig denk ich in einem gepackten Archiv (.jar) rumzufummeln.

Meine Frage ist halt gibt es eine Möglichkeit eine .jar datei zu ersetzen...
Also bei einem Update die Anwendung zu ersetzen und sozusagen neuzustarten.


----------



## Clayn (5. Dez 2012)

Also ich machs bei meinem Programm so mitm Updaten (Auch wenn man dann manuell Neustarten muss aber das kann man vllt auch iwie ändern) das zuerst die neue Jar bzw Jars runtergeladen werden in ne extra Datei und dann wird einfach per In/Outputstreams die Daten von den neuen Datein in die alte reingeschrieben quasi überschrieben. 

Java/Windows meckern nicht rum das die Datei gerade verwendet wird und beim nächsten starten ist das Update wirksam^^


----------



## tröööt (5. Dez 2012)

naja ... über das thema kann man streiten ...
fakt ist : es sollte 3 bereiche geben

1) user.home für user-files
2) shared.home für z.b. Programme die auch für andere user verfügbar sein sollen
3) SYSTEM

leider ist die umsetung von "shared.home" so das problem ...

es ist nun mal gerade unter windows die schlechte angewohnheit "programme" systemweit zu installieren ...
für multi-user systeme mit mehreren user-konten mag das auch sinnvoll sein ... allerdings braucht man zum zugriff auf alles außerhalb von user.home eben genau wie unter unix erhöte rechte ...

eine wirkliche revolution wäre es wenn man den leider nicht so gemeinten arm von windows mit den gruppen von unix kombinieren würde :

es gibt das globale user-dir ... unter win %SYSDRIVE%\Users ... unter unix /home ...
unterhalb dieses globalen ordners sind die einzelnen user.home dirs ...
und neben diesen sollte es einen "public" user geben ... also "C:\Users\public" und "/home/public" ...
und nun kommen die gruppen ins spiel : jeder "user" wird automatisch der gruppe "users" zugewiesen ... und diese gruppe hat r+w auf eben diese public-ordner ...

somit könnte man "normale anwendungen" in diesen public ordner installieren und alle hätte zugriff und würden ihre persönlichen einstellungen jeweils in ihrem user.home speichern ...

und das einzige was dann wirklich unter "C:\Programme" kommt (bzw das gegenstück unter unix) wären dann solche system-programme wie eben sicherheits-software, treiber-controller und sowas ...

java z.b. würde dann nicht mehr unter /usr/share oder C:\Programme zu finden sein sondern eben unter /home/public/bin bzw C:\Users\public\Programme ...


aber nein ... um so ne revolution durchzusetzen müsste man schon sein eigenes OS entwickeln und die software darauf entsprechend anpassen ...



aber mal genug OT ... back to topic

@TO
natürlich brauchst du immer eine zweite datei ... du hast das scheinbar nicht richtig verstanden ...

egal ob du den launcher mit in dein app-jar packst oder daneben legst : auf das aktuelle "laufende" jar kannst du NICHT schreibend zugreifen ...
was macht man also : man läd die neue version als TEMP-file runter ... startet dann UNABHÄNGIG einen neuen prozess und beendet die aktuelle instanz ...
der updater selbst hat dann nur die aufgabe die alte version zu löschen , die neue entsprechend wieder zu bennen und diese dann zu starten ...
alternativ kann sich dann der updater selbst löschen ...

OHNE eine (zumindest temporäre) zweite datei wird es NICHT gehen ...

außerdem : wer zwingt dich denn deine runtime auch auf dem desktop liegen zu haben ?

blödes bleistift : Minecraft ...
es gibt Minecraft.exe ... das ist der launcher ... und die eigentlichen programm-daten liegen dann unter %appdata%\.minecraft ...
ergo : der launcher prüft die version dieser daten und startet diese dann ...
gut .. das Minecraft.exe selbst NICHT die möglichkeit hat sich alleine upzudaten ... tja .. s***** design von Mojang ...

oder anderes beispiel : Steam ...
es gibt STEAM.EXE ...
während des updates läd steam.exe die aktuelle version und zusätzlich steamupdate.exe runter ...
was passiert : steam.exe startet unabhängig steamupdate.exe und beendet sich selbst ... steamupdate.exe wartet nun bis steam.exe beendet ist ... löscht steam.exe und beenent steam.tmp in steam.exe um ... danach wir eben diese neue steam.exe gestartet und steamupdate.exe löscht sich beim beenden selbst ...

und genau so musst du das auch programmieren ... anders geht es nun mal einfach nicht ...

@Clayn
ist zwar richtig das man während der runtime APP.jar einfach überschrieben kann ... das sollte man aber unterlassen ... denn so kann man z.b. daten "kaputt" machen bevor diese geladen werden
bleistift : du willst resource/img.png laden ... hast dieses aber in der neuen version umbenannt ... wenn du nun erst updatetest ... dann aber die alte version trotzdem laufen lässt knallt es wenn du versuchst resource/img.png zu laden .. dies aber nicht mehr existiert ...


----------



## Sephrox (5. Dez 2012)

Danke die Antwort war sehr hilfreich... So habe ich das Konzept bisher nicht verstanden...
aber so macht es Sinn. Das mit der 2. Datei meinte ich keine temp datei sondern eine zum Programm hinzugehörende 
Das mit den User-Files ist bei mir jetzt nicht unbedingt notwendig kann man aber für die nächsten male übernehmen... danke erstmal dafür

(kurz gehalten aufgrund der Arbeit)


----------



## tröööt (5. Dez 2012)

da es mehrere wege gibt eine java-app zu starten und damit entsprechend viele daten in ordnern zu "verstecken" kann man auch mit persistenten daten arbeiten ... es kommt auf dein design an


----------



## Guybrush Threepwood (5. Dez 2012)

Es gab vor längerer Zeit hier im Forum mal ein ähnlich gelagertes Code-Beispiel. Vielleicht hilft's: http://www.java-forum.org/allgemeine-java-themen/59729-updatemanager.html


----------



## Sephrox (12. Dez 2012)

Hey,

ja das hatte ich mir schon angeguckt ^^ also so wie ich es jetzt Verstanden habe funktioniert es auch 

Danke für die hilfreichen Tipps


----------

