# Muss EE sein oder EE+SE kombinieren?



## OnDemand (16. Mai 2015)

Hallo, jetzt mal ne blöde Frage...

Ich habe ein Webprogramm mit Primefaces, welches Daten aus der DB anzeigt und ein paar Buttons hat, welche Methoden aufrufen und Aufgaben anstoßen (Zb aktualisiere meineDatenbank jetzt). Da in Java EE keine Threads erstellt werden können brauch ich ne Lösung. Ich muss in ca 100 Kundendatenbanken etwas gleichzeitig updaten. Das geht nur mit Threads, da es sonst so  ewig lange dauert, alle nacheinander abzuarbeiten.  

So nun Plan A: Threads erstellen in Java EE, wie geht es richtig? Ich finde kein Tutorial, nur Erklärungen warum man es meiden soll. Wenn Threads dann laufen würden, ok.

oder Plan B, macht dies Sinn, die Logik auszugliedern?

Plan B: Die GUI mache ich auf JSF Basis, die Programmlogik lasse ich aber als JavaSE auf dem Server laufen, damit kann ich ja Threads erstellen etc.  Wie kann ich dann aber Methoden aus JSF anstoßen, welche sich in einem jar-JavaSE-Paket befinden, anstoßen?!

Ich hoffe mir kann jemand einen heißen Tipp geben.


----------



## stg (16. Mai 2015)

Der Titel allein lässt vermuten, dass du gar nicht genau weißt, was Java EE überhaupt ist. Hier solltest du zu allererst mal ansetzen und die Lücken schließen. Dir mangelt es ganz offensichtlich an grundlegendem Verständnis ... das kommt ja bei deinen ganzen Fragen hier immer wieder mal auf, wenn ich dir antworte.

Speziell zum Thema Threads hatte ich dir doch auch vor gar nicht allzulanger Zeit noch etwas geschrieben. Meine Aussage damals war nur, dass du nicht _selbst_ eigene Threads starten sollst, sondern das dem EJB Container überlassen sollst.


----------



## Carol (17. Mai 2015)

Plan A: Das nimmt dir der EJB-Container ab und das solltest du ihm auch überlassen. Wenn anstelle von Anleitungen davor gewarnt wird, irgendwas mit Threads in eine EJB-Anwendung hineinzufummeln, dann hat  das seinen Grund.

Plan B: Logik aus der GUI auszugliedern hat immer Sinn, wenn das Programm noch irgendwann in der Zukunft erweitert oder gepflegt werden soll.
Ich hoffe, du meinst, dass du aus JSF heraus Methoden in einem Java SE-Paket aufrufen willst. Das würde man technisch mit einem RMI-Server und einem Anwendungsprotokoll lösen. Am Ende hast du Remote Session Beans aus Java EE nachgebaut. Bevor du da selbst etwas bastelst, nimm lieber gleich Java EE.


TL;DR: mach dich richtig Java EE vertraut, wie es schon stg geschrieben hat. Alles andere Gebastel ist für den beschriebenen Anwendungsfall nur Zeitverschwendung.


----------



## OnDemand (17. Mai 2015)

Hi ihr Zwei, danke für euer Feedback. Nochmal zu den Threads, es steht immer, dass man kein extends Thread nutzen soll und kein Runable...Wie zum Geier erzeugt Glassfish dann einen Thread?


----------



## stg (18. Mai 2015)

NicoDeluxe hat gesagt.:


> Nochmal zu den Threads, es steht immer, dass man kein extends Thread nutzen soll und kein Runable...Wie zum Geier erzeugt Glassfish dann einen Thread?



Ganz recht, der Application Server erzeugt bei Bedarf neue Threads und führt deinen Code dort aus. Darum musst du dich selbst nicht kümmern. Wie das unter der Haube genau abläuft, kann dir an der Stelle egal sein, das ist ja das schöne. Um den ganzen Verwaltungs-Overhead musst du dich nicht kümmern. Und zum Thema hatte ich dir bereits in deinem letzten Thread einen Link gepostet, in dem das alles erklärt wird..


----------



## OnDemand (18. Mai 2015)

Moin stg,

ich muss doch aber Glassfish dazu bringen können einen Thread zu starten. Ich möchte in der Methode, dass jedes file in einem Thread heruntergeladen wird, dass kann ich nicht dem Zufall überlassen. Diese Methode unten wird aus einer Manager-Klasse mit @Schedule aufgerufen. Die Files werden alle brav herunter geladen, aber alle im selben Thread und alle nacheinander. (Sehe ich durch das loggen, alle paar Sekunden eine Datei)




```
@Asynchronous
    public static void loadLinks() {
		try {
	    Statement stmt;
	    stmt = conn.createStatement();
	    ResultSet result= stmt.executeQuery("SELECT * FROM links");
	    for (int i = 2; i < result.getMetaData().getColumnCount() + 1; i++) {
		while (resultUserLinksDropshipper.next()) {
		    fileName = resultUserLinksDropshipper.getString("userName") + File.separator + resultUserLinksDropshipper.getMetaData().getColumnName(i) + ".csv";
		    downloadLink = resultUserLinksDropshipper.getString(i);
		
		    if (downloadLink != null) {
			
			Downloader.downloadFile(downloadLink); //Das möchte ich in einem Thread machen lassen

		    }
		}
	    }
	    stmt.close();
	} catch (SQLException e) {
	} finally {
	    try {
		connI2S.close();
	    } catch (SQLException e) {
		e.printStackTrace();
	    }

	}
    }
```


----------



## stg (18. Mai 2015)

Bei dir wird die Methode #loadLinks() asynchron aufgerufen. Was du aber vermutlich willst, ist ein asynchroner Aufruf von #downloadFile() !


----------



## OnDemand (19. Mai 2015)

Huhu, hast recht. Aber auch downloadFile wird nur in einem Thread ausgeführt. Bekomm es nicht hin, dass jeder Download in einem seperaten Thread ausgeführt wird 

Habe folgenden Code zur Ausgabe der Tread-ID


```
System.out.println(Thread.activeCount());
			Thread t = Thread.currentThread();
			String name = t.getName();
			System.out.println("name=" + name);
```
Kommt aber immer die selbe Tread-ID, also wird auch nur einer erzeugt., richtig?


----------



## stg (19. Mai 2015)

Ja, schon klar. Und das musst du dem EJB Container irgendwie mitteilen. Dazu solltest du die Methode #downloadFile asynchron aufrufen und nicht die Methode, in der du über alle zu downloadenen Files iterierst. Ich glaub, das hab ich doch im letzten Beitrag schon geschrieben 


```
@Asynchronous public void downloadFile(String downloadLink) {
    Downloader.downloadFile(downloadLink)
}
```

Exception-Handling usw mal unberücksichtigt..

Übrigens: Was ich zuvor nicht gesehen habe, deine Methode #loadLinks() ist ja statisch.... das sollte sie aber mit nahezu 100%iger Sicherheit nicht sein.


----------



## OnDemand (19. Mai 2015)

die Methode downloadFile ist @Asy... ich schwööööre!


----------



## stg (19. Mai 2015)

Die Annotation @Asynchronous macht deine Methode nicht asynchron (was soll das denn genau bedeuten?) sondern markiert sie für den EJB Container nur derart, dass er weiß, dass er sie asynchron aufrufen soll.

Der Aufruf sieht aber so aus, dass du eine statische Methode #downloadFile() auf der Klasse Downloader aufrufst. Insbesondere rufst du sie _nicht_ auf einer durch den EJB Container verwalteten _Instanz_ auf, das kann doch dann so gar nicht funktionieren (womit wir abermals bei elementaren JEE Grundlagen gelandet wären...)


----------



## OnDemand (19. Mai 2015)

Hmmm ok, danke erstmal für deine Geduld!

Ich habe ne Klasse Schedule, LoadLinks und Downloader.

In der Klasse ScheduleMethode habe ich ne Klasse ladeLinks() welchjede 5 Stunden aufgerufen

```
@Schedule( hour="*/5" ,persistent=false)
    public static void ladeLinks() {
	DownloadManager.iterateLinks();
    }
```

In der DownloadManager.iterateLinks() geh ich über alle Links jeden Users. 
In dieser Methode wird dann für jeden hinterlegten Link folgendes aufgerufen

```
Downloader.downloadFile(downloadLink);
```

Warum ist das nicht in der Instanz vom EJB? Da muss ich nochmal lesen


----------



## stg (19. Mai 2015)

Hier bei dem geposteten Schnipsel das gleiche Problem, es fängt nur schon 1 oder gar 2 Ebenen höher an.

1. Bereits deine Methode #ladeLinks() sollte mit an Sicherheit grenzender Wahrscheinlichkeit _nicht_ statisch sein. 

Was DownloadManager.iterateLinks(); nun genau macht und was für Side-Effekte ausgelöst werden ist jetzt hier nicht ersichtlich, daher kann ich da nicht viel zu sagen. Ich vermute aber, dass es sicher auch hier wieder um eine statische Methode handelt, in diesem Fall dann von der Klasse DownloadManager. 

Generell verwaltet der EJB-Container (u.a.) Instanzen von Klassen. Wenn du vom EJB-Container angebotenen Funktionalitäten nutzen willst, dann musst du auch eine der von ihm bereitgestellten Instanzen nutzen und nicht irgendwelche selbst erstellten (oder gar dir Klassen selbst, wie in diesem Fall). So funktioniert das nicht. Du kannst trotz all der EJB-Annotationen usw deinen gesamten Code auch "normal" benutzen, ohne dass der eJB-Container irgendetwas davon mitbekommt und das genau machst du offenbar.


----------



## OnDemand (19. Mai 2015)

Das static hab ich überall entfernt danke.

Wann erstellt denn der EJB eine Instanz einer Klasse. Hab grad ganz schönes Gehinfasching..


----------



## stg (19. Mai 2015)

NicoDeluxe hat gesagt.:


> Wann erstellt denn der EJB eine Instanz einer Klasse.



Die EJB macht das gar nicht, sondern der Container! Wann, wie, wo und warum kann dir egal sein. Du meldest dich nur "Hey, ich brauch eine Instanz von XY" und bekommst mit Hilfe schwarzer Magie eine zugewiesen. Entweder per Dependency Injection oder manuell per JNDI lookup.

Aber nochmal .... dir fehlen elementare Grundlagen! Ich sag das ja nicht einfach so um dich irgendwie nieder zu machen oder so, sondern um dir zu helfen und damit aufzuzeigen, dass du dich da zunächst einmal einarbeiten solltest. Lies doch z.B. mal das JEE Tutorial von Oracle, und zwar komplett! Macht vielleicht nicht so viel Spaß wie das Programmieren selbst, aber ist mehr als sinnvoll. Da bist du dann jetzt vielleicht erstmal einige Tage nur mit Lesen beschäftigt, aber letzten Endes, wenn das Grundverständnis da ist, sparst du eine Menge Zeit bei der Entwicklung.


----------



## OnDemand (19. Mai 2015)

Hab schon ein Buch im Anschlag, komm nur nicht dazu


----------



## stg (19. Mai 2015)

Nimm dir die Zeit, langfristig sparst du Zeit und Nerven!

Firmen zahlen ihren Mitarbeitern schließlich auch nicht Lehrgänge für hunderte oder gar tausende von Euro, weil sie so nett sind, sondern weil es sich rechnet, wenn der Mitarbeiter danach produktiver arbeiten kann


----------



## OnDemand (19. Mai 2015)

Ja da hast du Recht =)

Danke dir trotzdem für deine Unterstützung, ist ja nicht die Regel hier!


----------



## OnDemand (20. Mai 2015)

Mein buch was ich habe ist nicht so der Brüller, irgendwie behandelt das Themen, die mich zur Zeit nicht interessieren. Kennt jemand dir Bücher EJB 3.1 professionell und Java EE 7: Enterprise-Anwendungsentwicklung leicht gemacht? Welches davon ist das bessere für einen vollumfänglichen Einstieg?


----------



## OnDemand (20. Mai 2015)

Stg, deine Hinweise bezgl. Background. Hab das Buch Java EE 7 Entwicklung leicht gemacht und finde schon auf den ersten paar Seiten deine Worte wieder (Container kennt Instanzen die mit new erzeugt werden, nicht) BING :rtfm:


----------

