# Multi User Problem



## Gelöschtes Mitglied 5909 (3. Dez 2008)

Meine Webapp ist sogut wie fertig und ich hab mal ein paar leute auf die Seite geschickt.
Schon kamen wieder Probleme: 

- nach dem Login fliegt man sofort wieder raus, obwohl ich den User in der HttpSession speicher
- wenn man ein Artikel in den Warenkorb legen will, tritt eine NullPointerException auf, weil der
EntityManager null ist - bei Stateless EJBs gehts, bei der Statefull Cart EJB nicht


```
@Stateful
@TransactionManagement(TransactionManagementType.CONTAINER)
public class ShoppingCart implements ShoppingCartLocal, Serializable {

    @PersistenceContext(unitName="webshop")
    private EntityManager   entityManager;
```


Sobald ich mit dem em was mache NullPointer, aber nur bei *dieser* EJB - alle anderen sind Stateless


```
else if (action.equals("login")) {
                User user = userManager.login(username, password);
                if (user != null) {
                    session.setAttribute("user", user);
                } 
                else {
                    request.setAttribute("error", "Login Failed.");
                }
                redirect(request, response, "/index.jsp");
            }
```

Den Logout mache ich so:


```
else if (action.equals("logout")) {
//                cart.remove();
                session.setAttribute("user", null);
                session.setMaxInactiveInterval(0);
                session = request.getSession(true);
                redirect(request, response, "/index.jsp");
            }
```

Wenn ich die auskommentierte methode der EJB die mit @Remove versehen ist aufrufe dann krieg ich ne EJBException

Das komische ist, wenn ich selber auf Localhost teste funktioniert das ganze - keine NPE bei der EJB und ich bleibe eingeloggt.
Irgendwie scheint die Session / EJB zuordnung nicht ganz zu klappen, obwohl das ja angeblich so toll sein soll :/


----------



## maki (3. Dez 2008)

Schwer zu sagen, vermute(spekuliere) dass die HttpSession neu angelegt wird und damit das Attribut user null ist.


----------



## Gelöschtes Mitglied 5909 (3. Dez 2008)

Ich hatte vorher in allen Servlets


```
request.getSession(true);
```

Jetzt hab ich das ganze ersetzt in



```
request.getSession();
```

mit gleichem ergebniss :/

durch forwarden wird die Session doch nicht beeinflusst oder?


```
private void redirect(HttpServletRequest request, HttpServletResponse response, String page) throws ServletException, IOException {
        RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(page);
        dispatcher.forward(request, response);
    }
```


----------



## maki (3. Dez 2008)

Kommt darauf an wie die Session gesetzt/gelesen wird.

Cookie oder URL Rewriting?

Letzteres ist nicht ganz ohne, wenn der Testserver das anders macht als deine Dev Kiste kann es da schon zu Problemen kommen.


----------



## Gelöschtes Mitglied 5909 (4. Dez 2008)

Danke erstmal, hab mir garkeine gedanken darüber gemacht wie der Server die Session verwaltet. Eine Frage dazu hätte ich noch: wenn ich Cookies verwende, muss ich dann die SessionUID manuell aus dem Cookie auslesen und mir die passende Session selber suchen oder macht der Server dass dann automatisch?

Ich verwende Glassfish als Appserver

Folgendes habe ich gefunden, was man in die sun-web.xml eintragen kann:


```
<session-config>
      <session-properties>
         <property name="enableCookies" value="true" />
<property name="enableURLRewriting" value="false" />
</session-properties>
   </session-config>
```

Reicht es wenn ich das mache oder muss ich mich sonst noch um etwas kümmern? Bei URLRewriting müsste ich jeden link mit encodeURL() codieren wenn ich das richtig verstanden habe.

Das wär erstmal das wichtigste was ich noch wissen muss 

Dann wäre es noch gut zu Wissen was ich machen muss, damit ich die Stateful EJB mit der @Remove Annotierten Methode entfernen kann und sie vom Container automatisch wieder erzeugt wird wenn eine neue Anfrage kommt.

So wie ich das in meinem tollen Buch gelesen habe sollte die Verwaltung der EJB ja eigentlich vom Container automatisch gemacht werden und ich müsste mich dann nicht darum kümmern. Als ich beim logout aber auch cart.remove() aufgerufen habe ist bei der nächsten Anfrage eine NoSuchEjbException geworfen worden. Muss ich dann per hand eine neue Instanz erzeugen? Die bisherige EJB (also die erste Instanz) habe ich mit der @EJB Annotation injected.
Eine ejbCreate() Methode wie es bei EJB 2.1 gab gibt es bei den von mir Verwendeten EJB 3.0 meines Wissens ja nicht.

Die EJB habe ich folgendermaßen in der web.xml konfiguriert:


```
<ejb-local-ref>
        <ejb-ref-name>cart</ejb-ref-name>
        <ejb-ref-type>Session</ejb-ref-type>
        <local-home/>
        <local>de.mas.ejb.session.ShoppingCartLocal</local>
        <ejb-link>de.mas.ejb.session.ShoppingCart</ejb-link>
    </ejb-local-ref>
```

Bei den Stateless EJBs habe ich das Problem natürlich nicht und der Warenkorb ist meine einige Statefull EJB.

Danke im vorraus


----------



## maki (5. Dez 2008)

Wenn ich dich richtig verstanden habe, hast du alle deine Probleme nur auf deinem "Testserver", nicht lokal.

Würdemich erstmal um das Problem mit den Sesions kümmern.
Habe keine Erfahrung mit Glassfish als Webserver, Tomat versucht erst die Cookies zu verwenden, wenn das nicht geht greift er auf URL rewriting zurück, cookies sind immer zu bevorzugen.
Beide Mechanismen unzen gleich aus deiner sicht, ausser eben die Sache mit der session die dann immer in der URL mitkodiert werden muss.

Mit isNew() kannst du prüfen ob eine Session neu ist, würde ich zu testzwecken mal probieren, wenn nciht,ist dein Problem ein anderes.


----------



## Gelöschtes Mitglied 5909 (7. Dez 2008)

so passt alles, danke nochmal maki


----------



## maki (7. Dez 2008)

Was war es denn?


----------



## Gelöschtes Mitglied 5909 (8. Dez 2008)

Cookies beim Glassfish aktiviert


----------

