# Stateful Session Bean will nicht "stateful" sein



## aemik (8. Nov 2010)

Hallo,

bin gerade dabei mich in EJB einzuarbeiten und habe ein Problem:
Benutze JBOSS, Eclipse und Java5.

Habe eine einfache Bean erstellt, die einen Counter verwaltet, der hochgezählt werden kann.
Annotation ist "Statuful", Remote Interface exisitiert und ist annotiert, Bean ist Serialisierbar.
Es werden 2 Methoden angeboten, die den counter auslesen bzw. hochzählen.

auf clientseite hab ich ein einfaches servlet, das sich über jndi lookup die bean holt, hochzählt und ausgibt.
Leider bleibt mein Zähler immer auf 1, wenn ich die Seite im Brwoser neu lade.

Es scheinbt so als dass ich jedesmla ein neues Objekt bekomme. Ich will aber das selbe.

Ich bin davon ausgegangen, dass sich die Bean ihren Zustand im Application Server merkt.
Habe ich irgendwo einen Denkfehler oder etwas falsch verstanden?

Danke für die Hilfe
aemik


----------



## FArt (8. Nov 2010)

aemik hat gesagt.:


> Hallo,
> 
> bin gerade dabei mich in EJB einzuarbeiten und habe ein Problem:
> Benutze JBOSS, Eclipse und Java5.
> ...



Nein, du hast nichts falsch verstanden. Vermutlich hast du etwas falsch gemacht.


----------



## FArt (8. Nov 2010)

P.S.: Bevor du jetzt kiloweise Code hier ablädst...

Baue mal Logging in deine Applikation ein und du wirst sehen wo dein Fehler liegt, z.B. darin, dass das Servlet bei jedem Call eine neue Session benutzt und somit auch immer wieder ein neuese SFSB erstellt...


----------



## aemik (8. Nov 2010)

Ok, schonmal danke für die ersten Hilfestellungen.

Beim Debuggen seh ich auf jeden Fall, dass jedesmal beim JNDI Lookup ein neues SessionBeanObjekt (andere Id) erstellt wird.

Ich logge mir die Session raus und sehe, bei jedem reload, dass es immer dieselbe ist.

Muss ich irgendwas konfigurieren an meinem JBOSS?


----------



## FArt (8. Nov 2010)

aemik hat gesagt.:


> Beim Debuggen seh ich auf jeden Fall, dass jedesmal beim JNDI Lookup ein neues SessionBeanObjekt (andere Id) erstellt wird.


Ja, das ist klar. Somit nutzt die eine Servletsession bei jedem Call eine neues SFSB.

Tipp: Stateful Session Beans Example, EJB Tutorial


----------



## aemik (8. Nov 2010)

Ok, hab das Beispiel gemacht und es läuft auch.
Aber was mich wundert:

Dort wird auch nur einmal die Bean geholt, in der jspInit() Methode, und dann quasi gehalten.
Sobald ich die Bean erneut hole, bekomm ich eine neue Instanz.

Dort tritt also das selbe Problem auf, dass ich bei mir auch hatte.
Soll nicht der Application Server den "State" der Bean halten, abhängig von der Session, egal wie oft ich sie Aufrufe?
Sonst gibt es doch garnkeinen Unterschied zwischen Stateless und Statefull.

Danke!


----------



## aemik (8. Nov 2010)

```
protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		
		response.setContentType("text/html;charset=ISO-8859-1");
		PrintWriter out = response.getWriter();
		
		try {
			InitialContext ic = new InitialContext();
			CounterRemote counter = (CounterRemote) ic.lookup("CounterBean/remote");
			ic.close();
			
			counter.incrementCounter();
			out.println("<html><body>");
			out.println(counter.getCounter());
			out.println("<form action=\"sessionBeanServlet\" method=\"post\">");
			out.println("<input type=\"submit\" value=\"Reload\">");
			out.println("</form>");
			out.println("<html><body>");
			
		} catch (Exception ex) {
			System.out.println("Error:" + ex.getMessage());
		}
	}
```

Mein Code ist total simpel. Trotzdem bekomm ich jedesmal eine neue Instanz.


----------



## Marcinek (8. Nov 2010)

Bei jedem Lookup bekommst du eine neue Stateful bean.

Du musst dir diese im Client merken. Der Vortei list, wenn du 2x eine Methode ausführst wird diese 100% vom gleichen Objekt im Server gehandelt. 

Vergleich: Wenn ich eine SLSB habe, dann habe ich keine Garantie, dass zwei aufeinanderfolgende aufrufe durch das gleiche Objekt bearbeitet werden!

SFSB ist *keine *Singelton Implementierung! Das Lookup ist wie eine "new" Methode in dem Fall.


~~

Generell würde ich davon absehen im Web Stateful zu arbeiten. Die Natur des HTTP ist Stateless.

Baue dir eine SLSB, die auf ein Singelton Objekt im Server zugreift und die entsprechenden Änderungen macht.


----------



## Deadalus (8. Nov 2010)

Du machst ja auch jedes mal einen Lookup nach dem Bean. So bekommst du halt jedes mal wenn du die Methode ausführst auch eine neue Instanz.  

Mach den Lookup nur ein einziges mal am besten im Constuctor und es sollte klappen. Übrigens, auch bei stateless Session Beans nur einmal lookup machen. Das reicht!


Btw. schon mal von @EJB gehört?


----------



## FArt (8. Nov 2010)

Deadalus hat gesagt.:


> Mach den Lookup nur ein einziges mal am besten im Constuctor und es sollte klappen.


Im Konstruktor von was? Vorsicht bei Instanzen die von einem Container verwaltet werden (z.B. Servlet). Hier auf keinem Fall im Konstruktor so was machen sondern in den für die Initialisierung bestimmen Callbackmethoden!!! Der Konstruktor läuft oft in einem von der Spec nicht abgedeckten Kontext!



Deadalus hat gesagt.:


> Übrigens, auch bei stateless Session Beans nur einmal lookup machen. Das reicht!


Reicht wofür? So weit ich weiß sind die Stubs in der Regel nicht synchronisiert. Ich rate von zweifelhaften, pauschalen Optimierungen ab...


Tja, da sieht man was EJB3 anrichtet. Früher, mit EJB2, hat man noch das Homeinterface über den Lookup bekommen und über create das Bean explizit erstellt. Gehalten hat man dann entweder den Beanstub oder das Handle auf das Bean... 
Da hilft, wie so oft, nur eines: nicht gleich mit Hacken loslegen sondern erst mal schauen, was man da eigentlich macht!


----------



## FArt (8. Nov 2010)

Marcinek hat gesagt.:


> Generell würde ich davon absehen im Web Stateful zu arbeiten.


Ja, das würde ich auch.



Marcinek hat gesagt.:


> Baue dir eine SLSB, die auf ein Singelton Objekt im Server zugreift und die entsprechenden Änderungen macht.



Aua. Singleton auf dem Server in einer Enterpriseumgebung... führe das bitte genauer aus. In der Regel würde ich sagen: bitte nicht!!!!!!!!


----------



## Marcinek (8. Nov 2010)

FArt hat gesagt.:


> Aua. Singleton auf dem Server in einer Enterpriseumgebung... führe das bitte genauer aus. In der Regel würde ich sagen: bitte nicht!!!!!!!!



Puhh.. Warum nicht? - Du musst nur aufpassen, dass sie synchron zu anderen Instanzen deines Appicationservers sind, wenn dein AppServer skaliert ist.

I.d.R. benutze ich Singeltons überall dort, wo ich auch hätte static methoden oder final Konstrukte nehmen können. Nach der Initialsierung des Servers ändern sich diese nicht mehr. 

Messages, Configurationen, Module, Lizenzen, 

Da meine Anwendungsserver hochgradig skaliert sind, kann ich da sowas wie einen globalen Counter nicht bringen ^^

Das, was der TO hier macht ist aber keine Enterprise anwendung nur weil er eine technologie benutz, die das im Namen hat ^^


----------



## aemik (8. Nov 2010)

dann verstehe ich einfach nicht den Unterschied zwischen den beiden Typen.

Ich hole mir über den Lookup jeweils eine Stateful und eine Statless bean und merke sie mir dann.
Wie unterscheidet sich ab dann ihr Verhalten?


----------



## FArt (8. Nov 2010)

Marcinek hat gesagt.:


> Puhh.. Warum nicht? - Du musst nur aufpassen, dass sie synchron zu anderen Instanzen deines Appicationservers sind, wenn dein AppServer skaliert ist.
> 
> I.d.R. benutze ich Singeltons überall dort, wo ich auch hätte static methoden oder final Konstrukte nehmen können. Nach der Initialsierung des Servers ändern sich diese nicht mehr.
> 
> ...



Den klassischen Singleton sollte man in einer Enterpriseumgebung (die jeder Applicationserver ist, gecluster oder nicht) nicht verwenden, schließlich ist ein Singleton nicht VM global! Der Entwickler sollte keine Annahmen machen müssen, wie das Assembly und Deployment einer Applikation geschehen könnte. bzw. sollte durch seine Implementierung keine Einschränkungen diesbezüglich voraussetzen.

Was er verwenden könnte wäre ab EJB 3.1 ein Singleton Bean oder eine einzelne Instanz einer Klasse als Service (z.B. ein SLSB, von dem nur eine Instanz gleichzeitig existieren darf oder ein MBean oder ...), aber nicht den klassischen Singleton.

Bestimmt Tricks und Kniffe eines Java-Entwicklers sollte sich ein Enterprise-Entwickler verkneifen.



Marcinek hat gesagt.:


> Nach der Initialsierung des Servers ändern sich diese nicht mehr.


Das ist ein Sonderfall, auf den sich ein Enterpriseentwickler nicht verlassen sollte! Implementierungen dieser Art würden ein Review nicht schadlos überstehen ;-)


----------



## FArt (8. Nov 2010)

P.S.: das SLSB mit nur einer Instanz ist auch ein übler Hack... ich habe ihn nur der Vollständigkeit halber erwähnt... *G*


----------



## Marcinek (8. Nov 2010)

Ich glaube das sind Systeme, die etwas komplexer sind, um sie hier zu besprechen...

~~

Ich kann es mir nicht verkneifen: Für jemanden der, smart-questions_de  in seiner Signatur predigt, meidest du Konsequent die benutzung des Edit Buttons


----------



## FArt (8. Nov 2010)

Marcinek hat gesagt.:


> Ich glaube das sind Systeme, die etwas komplexer sind, um sie hier zu besprechen...


Nicht wirklich. Ich spreche hier aus Erfahrung. Ich habe schon viele Probleme in Enterpriseapplikationen aufgedeckt, die ein "Java Entwickler" unwissentlich verbrochen hat. Leider äußert sich so ein Problem eben nur unter ganz gewissen Umständen, denn der Container entscheidet eben für sich, wann er was mit verschiedenen Instanzen so treibt und das Fehlverhalten ist dann in der Regel schwer zu lokalisieren.
Sicher sein kann man nur, wenn man gegen die Spec entwickelt, die man natürlich kennen muss. Die Spec ist relativ einfach zu lesen. Hier eine kurze Zusammenfassung von beliebten Fehlern: PMD - Rule Set: J2EE Rules. Da steht auch was über statische Felder mit Schreibzugriff, z.B. bei "Singletons"...



Marcinek hat gesagt.:


> Ich kann es mir nicht verkneifen: Für jemanden der, smart-questions_de  in seiner Signatur predigt, meidest du Konsequent die benutzung des Edit Buttons



Beiträge editieren ist immer so eine Sache... da kann vorher alles mögliche drin gestanden haben und plötzlich machen die folgenden Posts keinen Sinn mehr bzw. ein schneller Antworter hat gar keine Chance auf die Änderung einzugehen.


----------



## Marcinek (8. Nov 2010)

Die beans in meinen Anwendungen enthalten keine fachliche Logik.

Sie dienen als Dispatcher für die Business Schicht. 

Hier gibt es Konventionen und Implementierungen, die ein Sorglospacket bieten für EJBs.


----------



## FArt (8. Nov 2010)

Marcinek hat gesagt.:


> Die beans in meinen Anwendungen enthalten keine fachliche Logik.
> Sie dienen als Dispatcher für die Business Schicht.


Das ist egal.



Marcinek hat gesagt.:


> Hier gibt es Konventionen und Implementierungen, die ein Sorglospacket bieten für EJBs.


Ja, das kann sein. Das bedeutet aber, dass man nicht einfach empfehlen kann ein Singleton zu verwenden. Deshalb auch meine Bitte vorhin, genauer auf dein "Singleton" einzugehen, bevor wieder jemand auf die grandiose Idee kommt das Pattern für Singleton zu verwenden, dass viele Leute bei dem Stichwort assoziieren...


----------

