Avatar billede margitbork Nybegynder
07. december 2005 - 14:42 Der er 9 kommentarer og
1 løsning

Start af javaprogram fra et andet javaprogram

Jeg har en applikation (Client) der har nogle quartz schedulerede jobs som den står og afvikler. Ind i mellem skal denne applikation opdateres og i den forbindelse er der brug for en genstart af applikationen. Min ide er at lave en anden Java-applikation (StartClient) der bliver startet når opdateringen af Client er startet, (Client laver her en system.exit(exitcode)).
StartClient skal så vente lidt og derefter genstarte Client og selv lave en system.exit(0). Hvis Client stadig er igang med opdateringen gentager ovenstående sig. Men hvordan får jeg et javaprogram til at starte et andet program ?
Jeg har tidligere prøvet noget lignende med hvor jeg fra javaprogrammet kunne kalde en .bat fil, men det er ikke løsningen her da det skal være platforms-uafhængigt.

Jeg håber der nogle gode ideer herude.

Margit
Avatar billede mikkelbm Nybegynder
07. december 2005 - 14:53 #1
Hvis du vil til at lytte på processes, og det vil jeg mene du skal hvis du skal vente på at et program lukker ned, så bliver det svært at lave platformsuafhængigt.
Avatar billede arne_v Ekspert
07. december 2005 - 17:16 #2
Du kender Runtime.getRuntime().exec()

Den rigtige løsning er at:
  - ligge din app i en egen jar fil
  - lave en driver app som laver en URLClassLoader med den jar fil
  - loader med classloader og kalder din app i en tråd
  - i baggrunden checker om der kommer en ny jar fil
  - når det sker så stopper den tråde, GC'er classloaderen og starter forfra

Ligesom når man redeployer en ear til JBoss
Avatar billede mikkelbm Nybegynder
07. december 2005 - 19:31 #3
> Arne

Det var faktisk interessant. Det havde jeg slet ikke tænkt på. Har du et link der beskriver det lidt mere i detaljer?
Avatar billede arne_v Ekspert
08. december 2005 - 01:11 #4
kode:

package december;

import java.io.*;
import java.net.*;
import java.util.*;

public class SuperDynamic {
  private static void PGen(Date d) {
      try {
        OutputStream os = new FileOutputStream("test/P.java");
        PrintStream ps = new PrintStream(os);
        ps.println("public class P extends Thread {");
        ps.println("  public void run() {");
        ps.println("      try {");
        ps.println("          while(true) {");
        ps.println("              System.out.println(\"" + d + "\");");
        ps.println("              Thread.sleep(1000);");
        ps.println("          }");
        ps.println("      } catch(Exception e) {");
        ps.println("      }");
        ps.println("  }");
        ps.println("}");
        ps.close();
        os.close();
        Runtime.getRuntime().exec("javac -d test test/P.java").waitFor();
      } catch (Exception e) {
          e.printStackTrace();
      }
  }
  public static void main(String[] args) throws Exception {
      (new File("test")).mkdir();
      URL[] url = new URL[1];
      url[0] = new URL("file:test/");
      for(int i = 0; i < 3; i++) {
          PGen(new Date());
          URLClassLoader cl = new URLClassLoader(url);
          Thread p = (Thread)Class.forName("P", true, cl).newInstance();
          p.start();
          Thread.sleep(2500);
          p.interrupt();
          p.join();
          cl = null;
      }
       
  }
}

output:

Wed Dec 07 19:10:41 EST 2005
Wed Dec 07 19:10:41 EST 2005
Wed Dec 07 19:10:41 EST 2005
Wed Dec 07 19:10:44 EST 2005
Wed Dec 07 19:10:44 EST 2005
Wed Dec 07 19:10:44 EST 2005
Wed Dec 07 19:10:48 EST 2005
Wed Dec 07 19:10:48 EST 2005
Wed Dec 07 19:10:48 EST 2005
Avatar billede arne_v Ekspert
08. december 2005 - 01:13 #5
eksemplet er naturligvis fjollet, men det viser teknikken
Avatar billede arne_v Ekspert
08. december 2005 - 01:16 #6
eksemplet er naturligvis fjollet, men det viser teknikken
Avatar billede margitbork Nybegynder
08. december 2005 - 08:35 #7
Supert, jeg tester det lige af, så skal jeg nok komme tilbage med flere spørgsmål eller points.
Avatar billede margitbork Nybegynder
08. december 2005 - 14:59 #8
Jeg forsøger at styre applikationen via en klasse ApplicationController.java
Her har jeg en start, stop og restart metode. (restart kalder stop og dernæst start)
ApplicationController har p og cl som statiske objekter.
start indlæser min jar fil i URLClassLoader'en og starter tråden p.

Stop forsøger at stoppe p med følgende
            p.destroy();
            p.interrupt();
            p.join();
            cl = null;

for dernæst at slette resource.jar filen og omdøbe den nye resource2.jar fil til resource.jar.  MEN jeg kan ikke slette resource.jar - min applikation har åbenbart lås på den på en eller anden måde. Og det hænger nok også sammen med at det ikke ser ud til at min applikation bliver slukket korrekt ned.

Den applikation jeg starter er en klasse der v.hj.a. Quartz starter en række jobs.
Hvordan får jeg de jobs lukket korrekt ned igen ?
Den klasse der starter applikationen og forsøger at opdatere den styres også af Quartz.
Avatar billede arne_v Ekspert
09. december 2005 - 01:57 #9
det er meget vigtigt at den jar fil du loader fra med din egen classloader
*ikke* er i din normale classpath
Avatar billede margitbork Nybegynder
16. august 2006 - 11:05 #10
Vi har ændret vores approach, og forventer at vi kan få løst vores problemer ved at dritribuere applikationen v.hj.a InstallShield.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester