# Thread von Servlet aus starten



## nenico84 (3. Aug 2007)

Hallo,

ich brauch eure Hilfe!!! Bin jetzt schon seit 2 Tagen am Versuchen, einen Thread von einem Servlet aus zu starten!!! Vom Applet aus geht's einwandfrei, deshalb denk ich dass der Thread ok ist. Der Thread soll nur gestartet werden, er generiert dann ein Diagramm und speichert dieses als png ab. Zur Veranschaulichung hier ein vereinfachter Quellcode:


```
public class ImageMapDemo1 extends HttpServlet {
    Barchart b;    //Das ist der Thread
    
    public void init(){
        b = new Barchart();
        b.setDaemon(true);
        b.setPriority(Barchart.NORM_PRIORITY);
        b.start();
    }
    
    public void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
            response.setContentType("text/html;charset=UTF-8");
            PrintWriter out = response.getWriter();
            out.println("<html>");
            out.println("<head>");
            out.println("<title>JFreeChart Image Map Demo</title>");
            out.println("<style>body{background:blue;font-family:Verdana;}</style>");
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>Hallo Nico!</h1>");               
            out.println("<img src=\"barchart100.png\" \"width=\"600\" height=\"400\" border=\"0\" usemap=\"#chart\">"); //Hier wird das im Thread erzeugte png ausgegeben...
            out.println("</body>");
            out.println("</html>");
            out.close();      
    }
//... anschließend folgen noch die DoGet- und die DoPost-Methode, die aber auch die processRequest-Methode aufrufen...
```

Und hier der Code für den Thread (stark vereinfacht...)
Code:


```
public class Barchart extends Thread{
    
    public Barchart() {
         
    }
    
    /**
     * Start-Methode...
     */
    public void run(){
       //hier wird das Diagramm erzeugt und als png abgespeichert...
    }
```


... Mehr brauch ich doch nicht, oder? Oder muss ich in der build.xml-Datei vielleicht noch was verändern? Er compiliert alles und das Servlet läuft auch, er zeigt auch das png an, wenn ich eins einfüge, nur wird der Thread nicht gestartet (--> kein png erzeugt) und ich blick einfach nicht warum!!! Wäre super wenn mir jemand weiterhelfen könnte!!!... Vielen Dank!


----------



## Kim Stebel (3. Aug 2007)

init() wird imho nur beim Erzeugen des Servlet-Objekts aufgerufen und nicht bei jedem Request.


----------



## SlaterB (3. Aug 2007)

schau doch bisschen woran es liegt?!

z.B. das init, wird das überhaupt ausgeführt?

```
public void init(){ 
   System.out.println("init meldet sich zum Dienst");
   ....
}
```
schon weist du es,

genauso vielleicht Meldungen in Kosntruktor + run-Operation vom Thread usw.
bis du genau weist, was das Programm tut,

vielleicht speichert es ja das Bild woanders als du denkst?


----------



## nenico84 (3. Aug 2007)

Hab ich gemacht... sowohl die init() als auch der Konstruktor als auch die run()-Methode werden ausgeführt... überall kommt der System.out.println-Befehl durch... Die Bilddatei wird aber nirgends auf dem Rechner erzeugt...

Dann kann es eigentlich doch nur an der Syntax in der run-Methode liegen, oder? Es handelt sich um ein mit JFreeChart erstelltes Diagramm...

Die Syntax ist folgendermaßen:


```
public void run(){
CategoryDataset dataset = createDataset(); //ruft Dataset-Methode auf, die ein Dataset erzeugt
JFreeChart chart = createChart(dataset); //erzeugt mithilfe des Datensatzes eine Chart

//Nun wird das Chart in eine png-File geschrieben
try{
   final ChartRenderingInfo info = new ChartRenderingInfo (new StandardEntityCollection());
   final File file1 = new File("barchart100.png");
   ChartUtilities.saveChartAsPNG(file1, chart, 600, 400, info);
}
catch (IOException ex){
   ex.printStackTrace()
}

}
```

Hat jemand eine Ahnung?


----------



## SlaterB (3. Aug 2007)

....

hast du denn jemals in einem normalen Servlet ganz einfach ein Bild gespeichert oder eine Textdatei erzeugt?

wieso musst du mit so einem komplizierten Thread arbeiten?,
wieso musst du eine JFreeChart erzeugen, seltsamen .png-Dateinamen wählen und und und?

kannst du nicht mit einem klitzekleinen

```
new File("test.txt").createNewFile();
```
anfangen?
oder mit einer Textdatei in welche du "Hello World" reinschreibst?

immer ganz klein anfangen wenn etwas nicht funktioniert,
da musst du das Forum hier nicht unnötig mit komplizierten init-Operationen, Threads und Charts füllen

also ganz von vorne,
wie siehts mit folgenden Code aus, GANZ NORMAL in einem Servlet ausgeführt

```
File f = new File("test.txt");
System.out.println("neue Datei erstellen funktioniert?: "+f.createNewFile());
System.out.println("Datei befindet sich wo?: "+f.getAbsolutePath());
```
ist die Datei erzeugt und vorhanden?

(nimm die drastische Kritik nicht persönlich, soll nur unterstreichen wie total falsch das Vorgehen ist  )


----------



## nenico84 (3. Aug 2007)

Oh Mann, du bist gut! Hab's gefunden!!! Hat die ganze Zeit funktioniert, nur dass er die Datei im netbeans-Ordner in enterprise3\apache-tomcat-5.5\bin erzeugt! Und meine Suchmaschine hat's da irgendwie nicht gefunden... 

Dann muss ich jetzt nur noch einen Weg finden, wie er die Datei in den web-Ordner erzeugt (am besten per relativem Pfad), damit ich sie vom Servlet/JSP aus gleich aufrufen kann...

Danke für die Mühe und sorry für meine unkoordinierte Vorgehensweise ;-)


----------



## SlaterB (3. Aug 2007)

dazu muss ich persönlich passen, bin grad nicht  im Thema Servlets drin,

irgendwo wirst du dir sicher den Root-Path geben lassen können,
vielleicht neues Topic wenn sich hier keiner mehr meldet oder gar google-Suche 

mit MeineKlasse.class.getResourceAsStream oder ähnlich kann man evtl. Pfade relativ zu .class-Dateien bestimmen


----------



## Guest (6. Aug 2007)

hier bekommste den pfad vom verzeichniss in dem dein projekt liegt.
einfach dann entsprechenden ordnernamen anfügen falls gewünscht.




servlet:  String pfad = rq.getSession().getServletContext().getRealPath("/"); 


jsp: String pfad = application.getRealPath("/");


----------



## kasi (6. Aug 2007)

Wenn man vom Servlet aus einen Thread startet, ist der dann an die Server(Request)Timeout gebunden? - Wäre eigentlich unlogisch..

Wenn ich allerdings einen Thread im Servlet starte und das Ergebnis dort auch wieder verwenden will, dann schon, oder?!


----------



## SlaterB (6. Aug 2007)

wieso denn 'dann schon'?


----------



## kasi (6. Aug 2007)

naja, wenn der browser wartet doch auf nachricht vom server, wenn allerdings keine nachricht gesendet werden kann, bevor der server timeoutet, DANN wird doch auf client seite ne 400er meldung angezeigt..


----------



## SlaterB (6. Aug 2007)

daher wird z.B. der Thread, der das Servlet kontrolliert/ den Request durchführt, beendet,
interessiert deinen eigenen Thread aber auch nicht die Bohne


----------



## kasi (6. Aug 2007)

aber meinen client, der dann ne fehlermeldung bekommt. oder raff ich was nicht?!


----------



## SlaterB (6. Aug 2007)

wenn ein Server ein Timeout sendet, dann sollte das der Client mitbekommen, ja


----------



## kasi (6. Aug 2007)

gut. muss ich mir also nur noch überlegen, wie ich das timeout umgehe, ohne es hoch zu setzen, bzw. wie ich im server sage, dass er so lange thread.isalive zum browser schickt, bis thread tot is und dann der server das ergebnis sendet.


----------



## KSG9|sebastian (10. Aug 2007)

ach ja..Debugmodus wirkt Wunder


----------



## kasi (10. Aug 2007)

???


----------

