Config-File in jav packen möglich?

con-f-use

Erfahrenes Mitglied
Config-File in jar packen möglich?

Hallo zusammen,

ich habe eine kleine Application in ein ausführbares jar-Archiv gepackt. Bei besagter Application hat der User die Möglichkeit bestimmte Einstellungen zu machen um die GUI an seine Bedürfnisse anzupassen. Außerdem werden die Einträge, die der User in das ein oder andere Feld gemacht hat gespeichert und sind dann wieder vorhanden, wenn er das Programm das nächste Mal aufruft.
Bisher habe ich diese Einstellungen und Textfeld-Werte in einer Textdatei gespeichert. Diese Textdatei wird von der Application dann beim Start ausgelesen und entsprechend verwertet. Sie wird im gleichen Ordner erstellt, wie auch das jar-Archiv aus dem sich meine Application startet.

Ich finde es jetzt aber ein wenig blöd zwei Dateien - das jar-Archiv und die Config-Datei mit den Einstellungen zu haben.

Nun meine Frage: Ist es möglich die Config-Datei mit in das jar-Archiv zu packen, so dass meine Application sie aus dem Archiv beim Start auslesen kann und in ihr etwas speichern kann? Wenn ja, wo kann ich nachlesen wie genau das geht bzw. könnt ihr mir ein kleines Beispiel geben?
Würdet ihr mir eine andere (bessere Methode) empfehlen?

Ziel ist, wie gesagt, die ganze Application in einem File zu haben, dass man mitsammt der gemachten Einstellungen weitergeben kann.

Sorry, ich weiß diese Fragen sind etwas dumm. Ich bin gerade dabei mich in Java einzuarbeiten und es wäre einfach sehr mühsam, ewig nach so einer Kleinigkeit zu suchen, die man aus einem kleinen Beipiel, das wohl nicht mehr als 10 Zeilen Code braucht, sehr viel schneller lernen könnte.
Vielleicht helft ihr mir ja trotzdem. Schonmal vielen Dank!

G-r-uß von,
con-f-use
 
Zuletzt bearbeitet:
Hi,

sorry wegen der vielen try/catch :-), aber der Formeditor lässt mich auf die schnelle nicht an den generierten Code.

Zum Laden
Code:
    private void loadActionPerformed(java.awt.event.ActionEvent evt) {                                     
        
        //Aktueller Pfad
        String path = new File(".").getAbsolutePath();
        
        String jarPath = path + "/JavaApplication2.jar";
        
        JarFile file = null;
        
        try {
            file = new JarFile(jarPath);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        
        JarEntry entry =  file.getJarEntry("de/tutorials/config.properties");
        
        Properties props = new Properties();
        
        try {
            props.load( file.getInputStream(entry));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        
        value.setText(props.getProperty("foo"));
        
        try {
            file.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        
    }
Zum Speichern
Code:
  private void saveActionPerformed(java.awt.event.ActionEvent evt) {                                     
        //Aktueller Pfad
        String path = new File(".").getAbsolutePath();
        
        String jarPath = path + "/JavaApplication2.jar";
        
        JarFile file = null;
        System.out.println(path);
        try {
            file = new JarFile(jarPath);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        
        JarEntry entry =  file.getJarEntry("de/tutorials/config.properties");
        
        Properties props = new Properties();
        
        try {
            props.load( file.getInputStream(entry));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        
        props.setProperty("foo",value.getText());

        try {
 
            File storeFile = new File(path + "config.properties");
            FileOutputStream fos = new FileOutputStream(storeFile);
            props.store(fos,"");
            fos.close();
            
            //Erstelle tmp Archiv
            Updater.update(jarPath,storeFile.getAbsolutePath());
            
         if(storeFile.exists())
              storeFile.delete();
            
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch(IOException ix){
            ix.printStackTrace();
        }
        
        try {
            file.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        
    }
Der Updater zum erstellen des tmp Jar Archiv
Code:
package de.tutorials;

/**
 *
 * @author OliverT
 */
import java.io.*;
import java.util.*;
import java.util.zip.*;
import java.util.jar.*;

public class Updater {

   public static void update(String jarlocation, String filelocation) throws IOException {
    

      String jarName = jarlocation;
      String fileName = filelocation;


      File jarFile = new File(jarName);
      File tempJarFile = new File(jarName + ".tmp");

      JarFile jar = new JarFile(jarFile);
      System.out.println(jarName + " geöffnet.");


      boolean jarUpdated = false;

      try {


         Manifest jarManifest = jar.getManifest();
         JarOutputStream tempJar =
            new JarOutputStream(new FileOutputStream(tempJarFile));


         byte[] buffer = new byte[1024];
         int bytesRead;

         try {

            
            FileInputStream file = new FileInputStream(fileName);

            try {

               JarEntry entry = new JarEntry("de/tutorials/config.properties");
               tempJar.putNextEntry(entry);

               while ((bytesRead = file.read(buffer)) != -1) {
                  tempJar.write(buffer, 0, bytesRead);
               }

               System.out.println(entry.getName() + " erstellt.");
            }
            finally {
               file.close();
            }

            for (Enumeration entries = jar.entries(); entries.hasMoreElements(); ) {
              
               JarEntry entry = (JarEntry) entries.nextElement();

               //Überspringe vorhandene Datei
               if(entry.getName().equals("de/tutorials/config.properties")){
                   continue;
               }

                  InputStream entryStream = jar.getInputStream(entry);

                  // Schreibe in TempFile.
                  tempJar.putNextEntry(entry);

                  while ((bytesRead = entryStream.read(buffer)) != -1) {
                     tempJar.write(buffer, 0, bytesRead);
                  }
            }

            jarUpdated = true;
         }
         catch (Exception ex) {
            System.out.println(ex);
            
            // Füge Dummy Eintrag hinzu 
            tempJar.putNextEntry(new JarEntry("Dummy"));
         }
         finally {
            tempJar.close();
         }
      }
      finally {
         jar.close();
         System.out.println(jarName + " geschlossen.");


         if (! jarUpdated) {
            tempJarFile.delete();
         }
      }


      //Nicht möglich zur Laufzeit...
      if (jarUpdated) {
         jarFile.delete();
         tempJarFile.renameTo(jarFile);       
      }
   }
}
 
Zuletzt bearbeitet:
Hallo!

Ich denke, dass wird so ohne weiteres nicht funktionieren. Wenn die Anwendung in Form eines ausführbaren Jars vorliegt, kannst du zwar wunderbar darin lesen, jedoch nicht während der Ausführung der Anwendung hineinschreiben bzw. überhaupt Dateien innerhalb dieses Archives überschreiben.

Eine mögliche Variante wäre die einen kleinen Launcher vorne dran zu schalten der das aus und einpacken der entsprechenden Files aus einem separaten Prozess aus durchführt.

Gruß Tom
 
Hi,

da muss ich Tom Recht geben.
Eine Quick and Dirty Lösung wäre z.B. das Archiv temporär zu speichern und bei jedem Start Deines Progs z.B. über eine bat Datei das orig. jar Archiv zu löschen und das temp. jar in den ursprünglichen Namen umzubennnen.
Eleganter wäre es natürlich wie Tom es schon erwähnt hat.

Viele Grüße,
Olli
 
Eine weitere Möglichkeit unter Windows wäre die Einstellungen in die Registry zu schreiben. Du bräuchtest trotzdem eine Config-Datei in der Jar Datei, denn die Werte müssten beim ersten Programmstart in die Registry eingetragen werden. Nach dem ersten Start würde dann alles über die Registry laufen so das es sich erübrigen würde die Config-Datei zu updaten, welches bisher ein Problem darstellte.

http://www.galileocomputing.de/open...sel08_002.htm#Rxx747java080020400029B1F024100


Dann wäre allerdings die Plattformunabhängigkeit nicht gewährt.

@Confuse
Du fasst die Tatsache nur eine Datei weitergeben etwas falsch auf. Stimmt der Großteil der Windowsprogramme besteht nur aus einer Datei, genauer einer gepackten Datei. D.h. wenn du die exe gestartet und installiert hast, wirst du in deinem Programmordner einen Unterordner für dieses Programm finden, worin sich fast immer mehr als eine Datei befindet. Das Programm war also zur Weitergabe in eine Datei gepackt, zum Ausführen wird er allerdings in seinen eigenen Ordner extrahiert.

Das was du machen solltest ist, entweder einen Installer verwenden der deine Dateien in eine setup.exe verpackt, welche für dein Programm einen Ordner im Programmordner erstellt, deine Programmdateien dort extrahiert, und gegebenfalls Verknüpfungen erstellt.
Oder du nimmst einen Ordner myprogram. Tust deine Jardatei, die Configdatei, und andere Dateien wie Icons, Bilder in diesen Ordner und packst diesen mit einem Zipprogramm. So hast du zur Weitergabe nur eine Zipfile. Der User wird dann dein Programm entpacken und einen Ordner erhalten worin er alles findet was dein Programm benötigt.

Vg Erdal
 
Hallo!

Das Java Preferences API ist Platform unabhängig ;-) und zwar gerade deshalb, da vom letztendliche Backing Store (Registry unter Windows, Filesystem unter Linux) abstrahiert wird ;-)
Weiterhin löst das nicht das Problem mit der Verteilung der Anpassungen... du könntest beispielsweise einen WebService anbieten an den deine User ihre Anpassungen schicken könnten. Von dort könnte sie dann ein anderer User wieder beziehen. Hat ein user keine Internetverbindugn muss er eben mit seinen lokalen oder den Standardeinstellungen klar kommen.

Gruß Tom
 
Danke für die Berichtigung! Also noch ein Grund die Preferences API zu nutzen.

Für Desktopanwendungen welche keine Internetverbindung brauchen, würde doch die Preferences API eine Config-Datei erübrigen, behaupte ich jetzt mal, ganz vorsichtig. :)


Vg Erdal
 
Also erstmal danke an auch alle! Es ist also doch etwas komplizierter, als ich dachte. Ich werde das erstmal hinten anstellen, weil es dringenderes gibt, was in Java beherrschen will und weil die Application so klein und handlich bleiben soll, wie sie ist.

Es wäre halt einfach so eine Art Sahnehäubchen gewesen, dass ganze auch noch als eine einzige Ausführbare Datei vorliegen zu haben. Die Preference API werde ich mir trotzdem nochmal anschauen und ein wenig mit rumspielen.

Bei meiner Applikation handelt es sich wirklich nur um eine Kleinigkeit, die in ein jar verpackt nicht größer als 30 KB ist. Einen Installer oder einen Loader zu benuzten wäre da, wie mit Kanonen auf Spatzen zu schießen.

@flashray
flashray hat gesagt.:
@Confuse
Du fasst die Tatsache nur eine Datei weitergeben etwas falsch auf. Stimmt der Großteil der Windowsprogramme besteht nur aus einer Datei, genauer einer gepackten Datei. D.h. wenn du die exe gestartet und installiert hast, wirst du in deinem Programmordner einen Unterordner für dieses Programm finden, worin sich fast immer mehr als eine Datei befindet. Das Programm war also zur Weitergabe in eine Datei gepackt, zum Ausführen wird er allerdings in seinen eigenen Ordner extrahiert.

Das was du machen solltest ist, entweder einen Installer verwenden der deine Dateien in eine setup.exe verpackt, welche für dein Programm einen Ordner im Programmordner erstellt, deine Programmdateien dort extrahiert, und gegebenfalls Verknüpfungen erstellt.
Oder du nimmst einen Ordner myprogram. Tust deine Jardatei, die Configdatei, und andere Dateien wie Icons, Bilder in diesen Ordner und packst diesen mit einem Zipprogramm. So hast du zur Weitergabe nur eine Zipfile. Der User wird dann dein Programm entpacken und einen Ordner erhalten worin er alles findet was dein Programm benötigt.

Vg Erdal
Hehe, und du unterschätzt glaube ich mein Können etwas. Mir ist durchaus klar, was der Unterschied zwischen einem Installer und dem eigentlichen Programm ist und ich glaube, es ist auch schwer einen Computer zu nutzen, ohne dass man weiß, dass Programme in einen Festplattenordner installiert werden und dort dann auf mehere Files verteilt sind.
Ich weiß du meinst es gut, aber diese Belehrung war wenig sinnvoll.
 
Zurück