Muss EE sein oder EE+SE kombinieren?

OnDemand

Top Contributor
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.
 
Zuletzt bearbeitet:

stg

Top Contributor
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

Mitglied
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

Top Contributor
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

Top Contributor
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

Top Contributor
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)



Java:
 @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();
	    }

	}
    }
 
Zuletzt bearbeitet:

stg

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

OnDemand

Top Contributor
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

Java:
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?
 
Zuletzt bearbeitet:

stg

Top Contributor
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 :D

Java:
@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.
 
Zuletzt bearbeitet:

stg

Top Contributor
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

Top Contributor
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
Java:
 @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
Java:
Downloader.downloadFile(downloadLink);

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

stg

Top Contributor
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

Top Contributor
Das static hab ich überall entfernt danke.

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

stg

Top Contributor
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.
 

stg

Top Contributor
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

Top Contributor
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

Top Contributor
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 :D:rtfm:
 
Zuletzt bearbeitet:

Ähnliche Java Themen

Neue Themen


Oben