Avatar billede jespersahner Nybegynder
05. januar 2007 - 18:28 Der er 7 kommentarer og
1 løsning

Scheduled Task stopper ikke

Dette er ikke direkte et Java-spm., men jeg prøver alligevel; ellers må jeg forsøge i en anden kategori.

Jeg forsøger at starte et task vha. Windows XP "Scheduled Task". I mit tilfælde er task'et blot et Java-program, som jeg kalder fra en .bat-fil. I definitionen af task'et har valgt at task'et skal afvikles hvert 5. min., og jeg har markeret for "Stop the task if it runs for: 1 min." Task'et starter fint, men det afbrydes ikke efter 1 min. (jeg har med vilje sat grænsen lavt for at fremprovokere afbrydelse inden normal afslutning), hvilket jeg ikke forstår. Hverken .bat-fil/prompt-vindue lukker, eller java.exe stoppes. Når task'et igen efter 5 min. forsøges startet, er det allerede kørende, og så har man balladen.

Nogle forklaringer på, hvorfor task'et ikke afbrydes?
Avatar billede arne_v Ekspert
05. januar 2007 - 18:37 #1
det stillede spoergsmaal besvares nok bedst i Win XP kategorien

en java relevant workaround ville vaere at starte en 60 sekunders timer
i dit java program som kalder System.exit
Avatar billede jespersahner Nybegynder
05. januar 2007 - 20:43 #2
->arne_v: Jeg vil egentlig gerne følge en Java-workaround, men..
Konkret har jeg en applikation, som jeg gerne vil have kørt f.eks. hvert 5 min. Af og til ender applikationen i en deadlock (måske noget Swing-fnidder). Jeg har derfor behov for med 100% sikkerhed at kunne afbryde denne deadlock, og jeg ved ikke, om jeg altid vil kunne afbryde en sådan deadlock, hvis applikationen afvikles med en timer/kører i en seperat tråd (under samme JVM).

Alternativt er der den hårde måde med Runtime.exec("java.."), som jo vil sikre, at applikationen afvikles i sin egen JVM. Hvis deadlock forekommer, kan jeg så videre benytte Runtime.exec("taskkill.."). Denne måde minder i det store og hele vel om "Scheduled Task" i Windows XP.

Har du et bud på, hvad der er bedst her i forhold til problemet omkring deadlocks?
Avatar billede arne_v Ekspert
06. januar 2007 - 04:14 #3
umiddelbart har jeg en fin tillid til timer + System.exit

men den tillid er kun baseret på en fornemmelse
Avatar billede jespersahner Nybegynder
25. april 2007 - 23:34 #4
-> arne_v: Jeg har etableret en løsning ved brug af ProcessBuilder i stedet for Runtime.exec().

Smid gerne et svar.
Avatar billede arne_v Ekspert
30. april 2007 - 00:31 #5
det er ikke åbenlyst for mig hvad forskellen på de to er i denne kontekst

jeg frafalder point her
Avatar billede jespersahner Nybegynder
30. april 2007 - 02:03 #6
->arne_v: Der er vist ikke den store forskel på Runtime.exec() og ProcessBuilder, men den sidste anbefales under 1.5/5.0. Det er dog stadig aktuelt med "taskkill". Min løsning ser skematisk således ud:
ProcessBuilder pb;
Process proc;
String oneLine;
BufferedReader stdOut;
try {                       
    pb=new ProcessBuilder("cmd.exe","/c","copy","java.exe","mytask.exe");
    pb.directory(new File("C:/Programmer/Java/jdk1.5.0_10/bin"));
    proc=pb.start();                       
    stdOut=new BufferedReader(new InputStreamReader(proc.getInputStream()));
    while ((oneLine=stdOut.readLine())!=null);
    stdOut.close();
    pb=new ProcessBuilder("cmd.exe","/c","START \"Mytask"\" /MIN mytask -classpath ... Go","EXIT");
    pb.directory(new File("C:/Programmer/Java/jdk1.5.0_10/bin"));
    proc=pb.start();
    stdOut=new BufferedReader(new InputStreamReader(proc.getInputStream()));
    while ((oneLine=stdOut.readLine())!=null);
    stdOut.close();
    pb=new ProcessBuilder("cmd.exe","/c","taskkill","/f","/im","mytask.exe");
    pb.directory(new File("C:/Programmer/Java/jdk1.5.0_10/bin"));
    proc=pb.start();
    stdOut=new BufferedReader(new InputStreamReader(proc.getInputStream()));
    while ((oneLine=stdOut.readLine())!=null);
    stdOut.close();
    pb=new ProcessBuilder("cmd.exe","/c","erase","mytask.exe");
    pb.directory(new File("C:/Programmer/Java/jdk1.5.0_10/bin"));
    proc=pb.start();
    stdOut=new BufferedReader(new InputStreamReader(proc.getInputStream()));
    while ((oneLine=stdOut.readLine())!=null);
    stdOut.close();
} catch (IOException ex) {
    ex.printStackTrace();
}

Fidusen med at kopiere java.exe til mytask.exe er, at man derved kan foretage taskkill på netop mytask.exe uden af afbryde java.exe. Helt overordnet fungerer løsningen fint i forhold til hårdt at afbryde en eventuel deadlock ved brug af Windows-kommandoen taskkill. Mig bekendt har man pt. ikke en lignende mulighed i en ren Java-løsning, og under normale omstændigheder bør det heller ikke være nødvendigt med disse kunstgreb for at afbryde et program.

Lukker spm.
Avatar billede arne_v Ekspert
30. april 2007 - 04:07 #7
Prøvede du med en timer ?

import java.util.*;

public class Runner {
    public static void main(String[] args) throws Exception {
        Timer t = new Timer();
        t.schedule(new Killer(), Long.parseLong(args[1]));
        Class.forName(args[0]).getMethod("main", new Class[] { String[].class }).invoke(null, new Object[] { new String[0] });
        t.cancel();
    }
}

class Killer extends TimerTask {
    public void run() {
        System.out.println("Killed !");
        System.exit(0);
    }
}

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

public class Dummy {
    public static void main(String[] args) throws Exception {
        Scanner scn = new Scanner(System.in);
        System.out.print("Enter name: ");
        String s = scn.next();
        System.out.println(s);
    }
}

java Runner Dummy 10000
Avatar billede jespersahner Nybegynder
30. april 2007 - 22:08 #8
->arne_v: Ja, din løsning virker fint, og det gør en konstruktion med at pakke hele programmet ind i en Thread og så kalde Thread.join(time) efterfulgt af System.exit også. Min løsning er set i bakspejlet derfor nok lidt "overkill" men dog sikker.

Uanset løsning har jeg dog konkret behov for et andet Java-program til at genstarte det stoppede program (stoppet med System.exit eller taskkill). Det grundlæggende problem er, at man ikke "inden for samme JVM" kan rydde op i en deadlock. Har man yderligere behov for multiple threads (hvor deadlocks kan forekomme), må man altså nok starte multiple JVM'er op, hvilket sikkert ikke er problemfrit i forhold til memory.

Jeg har dog læst mig frem til, at der omkring dette problem er en såkaldt "Isolation API" i støbeskeen, se http://jcp.org/en/jsr/detail?id=121. Har du kendskab til denne?
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