# JBoss6 Remoting



## Gast2 (27. Apr 2011)

Hallo zusammen,

ich versuche grad einen Service von einem Client aufzurufen, so wie es hier beschrieben ist
Chapter6.JBoss EJB 3.0 extensions

Interface

```
@Remote
public interface AngebotRemoteService {

	Set<Angebot> getAngebote();
}
```
Impl:

```
@Stateful
public class AngebotRemoteServiceImpl implements AngebotRemoteService{
    
	@Override
	public Set<Angebot> getAngebote() {
//....
			return angebote;
	}
}
```

Client:

```
public class Client{

	public static void main(String[] args) {

		AngebotRemoteService angebotContainerService = null;
		// lookup the account manager bean
		try {
			Context context = new InitialContext();
			angebotContainerService = (AngebotRemoteService) context
					.lookup(AngebotRemoteService.class.getName());
		} catch (NamingException ne) {
			throw new RuntimeException("Could not lookup AngebotRemoteService: ",
					ne);
		}
}
```

Exeption

```
Exception in thread "main" java.lang.RuntimeException: Could not lookup AngebotRemoteService: 
	at main.Main.main(Main.java:30)
Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
	at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:645)
	at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
	at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:325)
	at javax.naming.InitialContext.lookup(InitialContext.java:392)
	at main.Main.main(Main.java:28)
```

Server Log

```
12:16:29,476 INFO  [org.jboss.ejb3.proxy.impl.jndiregistrar.JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

	AngebotRemoteServiceImpl/remote - EJB3.x Default Remote Business Interface
	AngebotRemoteServiceImpl/remote-remote.AngebotRemoteService - EJB3.x Remote Business Interface
```
Hab ich ein falsche namen im lookup angegeben oder fehlen mir irgendwelche Configs?

Danke und Gruß


----------



## mvitz (27. Apr 2011)

Steht doch da: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial

Weiß gerade nicht genau wie das File heißen müsste, ansonsten geht aber auch per System.setProperty

z.B. so:

```
Hashtable environment = new Hashtable();
            environment.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
            environment.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
            environment.put(Context.PROVIDER_URL, "jnp://10.200.1.21:1099"); // remote machine IP
            InitialContext context = new InitialContext(environment);
```


----------



## Gast2 (27. Apr 2011)

Mit File ist es schöner mal googlen.

Ja manchmal wurden die Props angegeben manchmal nicht war mir nicht sicher.

Aber wahrschenlich ohne Props muss der Client in der gleichen JVM laufen.


----------



## mvitz (27. Apr 2011)

Jap glaube ich auch. Wobei in der selben VM funktioniert glaube ich sogar so Application Client, dann kann man sogar normales DI nutzen.


----------



## Gast2 (27. Apr 2011)

Ja ist ja eher selten der Fall.

Zu dem JNDI Binding noch kurz eine Frage:
ich habe das Konstrukt von oben, warum wird das an 	
AngebotRemoteServiceImpl/remote gebunden und nicht an das Interface AngebotRemoteService/remote?

Also kurz nochmal zur Verständigung der aufruf geschieht jetzt schon RMI?


----------



## Gast2 (27. Apr 2011)

Wenn ich den Service Aufrufe bekomme ich eine CNFE, benötige ich noch irgendwelche jars auf dem Client?

```
log4j:WARN No appenders could be found for logger (org.jnp.interfaces.TimedSocketFactory).
log4j:WARN Please initialize the log4j system properly.
Exception in thread "main" java.lang.reflect.UndeclaredThrowableException
	at $Proxy3.getAngebote(Unknown Source)
	at main.Main.main(Main.java:40)
Caused by: java.lang.ClassNotFoundException: org.jboss.weld.context.ContextNotActiveException
	at org.jboss.remoting.serialization.ClassLoaderUtility.loadClass(ClassLoaderUtility.java:103)
	at org.jboss.remoting.loading.RemotingClassLoader.loadClass(RemotingClassLoader.java:94)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:247)
	at org.jboss.remoting.loading.ObjectInputStreamWithClassLoader.resolveClass(ObjectInputStreamWithClassLoader.java:179)
```


----------



## maki (27. Apr 2011)

Ja, nämlich die jboss-as-client jar


----------



## mvitz (27. Apr 2011)

Ja. Wenigstens deine eigenen Interfaces und dann noch Dinge wie jboss-client.jar (wobei die mittlerweile glaube ich aufgedrößelt sind).


----------



## Gast2 (27. Apr 2011)

Ja eigene Interface ist klar .

Ja in dem Ordner JBoss/client sind ziemlich viele jars. Ich schau mal nach der as client jar.

Der Dateiname ist jndi.properties

EDIT: Aufgedrösselt ist gut^^. Hab jetzt mal alles mit client drin, aber immer noch nicht richtig.
jboss-client.jar
jbosssx-as-client.jar
jbosssx-client.jar
jnp-client.jar

Muss ja irgendwo stehen was ich alles brauch :rtfm:


----------



## Gast2 (27. Apr 2011)

Also ich hab jetzt nur die weld-core-no-jsf.jar eingebunden, damit hats geklappt.

Jetzt hab ich so ein Gerüst

```
@Stateful
public class AngebotRemoteServiceImpl implements AngebotRemoteService{

  
    @Inject
    private MyDao dao;

    @Inject
    private UserRemoteBean userBean;
    
	@Override
	public Set<Angebot> getAngebote() {
		Set<Angebot> angebote = new HashSet<Angebot>();
		
		angebote.add(dao.findAngebote());
		if(userBean.getName().equals("test")){
			//tu was		}
		return angebote;
	}
}
```

Wenn ich auf das UserBean zugreife bekomme ich folgende Exception

```
Exception in thread "main" javax.ejb.EJBException: org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type javax.enterprise.context.SessionScoped
	at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.handleExceptionInOurTx(CMTTxInterceptor.java:183)
	at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:251)
	at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.required(CMTTxInterceptor.java:349)
```

Bean

```
@Stateful
@SessionScoped
public class UserRemoteBean{
	
	private String name;
```

Darf das Bean keinen SessionScoped haben? Versteh glaub das Problem gerade nicht ganz.


----------



## Gast2 (27. Apr 2011)

Ich glaub mir fehlt das Verständniss noch.

Also mit JSF war es kein Problem ich habe eine UserBean gemacht die SessionScoped war, so habe ich die User Infomationen nicht verloren und es konnten sich mehrere Benutzer anmelden.

Aber wie funktioniert sowas nun über einen DesktopClient damit man so eine UserBean SessionScoped machen kann?

EDIT:
Irgendwie steh ich grad aufm Schlauch, muss ich bei einer Desktopclient-Server Anwendung das Session Handling selber machen? Ich dachte mit EJB geht sowas.
Ich will einfach 2 User anmelden und die Daten an die Session koppeln.???:L
Oder muss ich die UserDaten auf den Client speichern und jedes mal mit über die Leitung schicken?

Ich mach mal ein kleines Bsp:
Serverseite
Interface:

```
@Remote
public interface LoginRemoteService {
	
	public void login(String name, char[] pwd);
}
```

Impl:

```
@Stateful
public class LoginRemoteServiceImpl implements LoginRemoteService{
	
	@Inject
	private UserRemoteBean user;
	
	
	@Override
	public void login(String name, char[] pwd){
		String loginUser = name.toUpperCase();
		if(!pruefen){
			loginUser = "Unknown User";
		}
		user.setName(loginUser);
		System.out.println(user.getName());
	}
}
```

Bean

```
@Stateful
//@SessionScoped--> geht nicht siehe oben exception
public class UserRemoteBean{
	private String name;
	private String pwd;
	
	public void setName(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
	public String getPwd() {
		return pwd;
	}
	
}
```

Service ist der gleiche von oben.

Wenn ich jetzt auf dem Client das hier mache ist der userBean.getName immer NULL :bahnhof:

```
public class Client{

	public static void main(String[] args) {

		Hashtable environment = new Hashtable();
        environment.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
        environment.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
        environment.put(Context.PROVIDER_URL, "jnp://127.0.0.1:1099"); // remote machine IP

		// lookup the account manager bean
       	AngebotRemoteService angebotRemoteService;
	LoginRemoteService loginService;
		Context context = null;
		try {
			context = new InitialContext(environment);
			angebotRemoteService = (AngebotRemoteService) context
			.lookup("AngebotRemoteServiceImpl/remote");
			loginService = (LoginRemoteService) context
			.lookup("LoginRemoteServiceImpl/remote");
		} catch (NamingException e1) {
			e1.printStackTrace();
		}

loginService.login("test", new char[]{'a'});
angebotRemoteService.getAngebote(); -->NPE userName ist null :bahnhof:
```

Kommt mir so vor als wären die Beans in unterschiedlichen sessions...


----------



## Gelöschtes Mitglied 5909 (27. Apr 2011)

Hab noch nicht allzuviel mit EJBs gemacht, aber muss nicht statt 


```
@Inject
    private UserRemoteBean user;
```

@EJB hin?


```
@EJB
    private UserRemoteBean user;
```


----------



## Gast2 (28. Apr 2011)

raiL hat gesagt.:


> Hab noch nicht allzuviel mit EJBs gemacht, aber muss nicht statt
> 
> 
> ```
> ...



Das Bean wir injected das passt schon, aber irgendwie bekomm ich bei jedem Service aufruf eine neue Session ID. Also hab ich dem Bean eine Session gegeben z.B. @ApplicationScoped jetzt hat halt jeder User den gleichen Namen und pwd, sobald sich ein neuer Benutzer anmeldet wird das Bean überschrieben, was ja Schwachsinn ist, darum wollte ich @SessionScoped verwenden aber irgendwie geht das nicht, da

```
Exception in thread "AWT-EventQueue-0" javax.ejb.EJBException: org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type javax.enterprise.context.SessionScoped
	at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.handleExceptionInOurTx(CMTTxInterceptor.java:183)
	at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:251)
	at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.required(CMTTxInterceptor.java:349)
	at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.invoke(CMTTxInterceptor.java:209)
	at org.jboss.ejb3.tx2.aop.CMTTxInterceptorWrapper.invoke(CMTTxInterceptorWrapper.java:52)
	at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
	at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
	at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
	at org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42)
	at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
	at org.jboss.ejb3.security.Ejb3AuthenticationInterceptorv2.invoke(Ejb3AuthenticationInterceptorv2.java:182)
	at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
	at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:41)
	at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
	at org.jboss.ejb3.BlockContainerShutdownInterceptor.invoke(BlockContainerShutdownInterceptor.java:67)
	at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
	at org.jboss.ejb3.core.context.CurrentInvocationContextInterceptor.invoke(CurrentInvocationContextInterceptor.java:47)
	at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
	at org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor.invoke(CurrentInvocationInterceptor.java:67)
	at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
	at org.jboss.ejb3.interceptor.EJB3TCCLInterceptor.invoke(EJB3TCCLInterceptor.java:86)
	at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
	at org.jboss.ejb3.stateful.StatefulContainer.dynamicInvoke(StatefulContainer.java:603)
	at org.jboss.ejb3.session.InvokableContextClassProxyHack._dynamicInvoke(InvokableContextClassProxyHack.java:53)
	at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:91)
	at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82)
	at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:898)
	at org.jboss.remoting.transport.socket.ServerThread.completeInvocation(ServerThread.java:791)
	at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:744)
	at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:548)
	at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:234)
```

Es muss doch ein Session Handling dafür geben. Oder wie aktivier ich den Context????:L


----------



## Gast2 (28. Apr 2011)

raiL hat gesagt.:


> Hab noch nicht allzuviel mit EJBs gemacht, aber muss nicht statt
> 
> 
> ```
> ...



Ich glaube das ist für DI auf der Clientseite

Seite 5 letztes Beispiel
EJB 3 Session Beans - Developer.com


Aber es kann doch nicht sein dass ich mein UserBean auf der Client Seite speicher und jedes mal mit über die Leitung schicke, dass ich die Infos habe.

Weiß jemand eine andere Möglichkeit für das Remote SessionHandling, damit die UserDaten eindeutig zu Session zugeordnet werden können?


----------



## Gelöschtes Mitglied 5909 (28. Apr 2011)

Hast dus mal probiert? Ich hätte vermutet, dass er es mit @Inject zwar richtig injected, aber nicht aus dem EJB Container der die States verwaltet. Kann aber auch gut sein dass ich mich irre. Anonsten keine Ahnung, sorry


----------



## Gast2 (28. Apr 2011)

raiL hat gesagt.:


> Hast dus mal probiert? Ich hätte vermutet, dass er es mit @Inject zwar richtig injected, aber nicht aus dem EJB Container der die States verwaltet. Kann aber auch gut sein dass ich mich irre. Anonsten keine Ahnung, sorry



Jop hab es versucht. Macht gar kein Unterschied also ich hab den Unterschied zwischen @EJB und @Inject jetzt nicht so ganz kapiert.


----------



## FArt (29. Apr 2011)

SirWayne hat gesagt.:


> Ich glaub mir fehlt das Verständniss noch.



Absolut... StatefulSessionBeans... Servletsession... die Konzepte dahinter. Da fehlt noch eine Menge Grundwissen. Obige Fehlermeldung in Verbindung mit der Doku ist eindeutig:

SessionScoped (Java EE 6 )


----------



## Gast2 (29. Apr 2011)

FArt hat gesagt.:


> Absolut... StatefulSessionBeans... Servletsession... die Konzepte dahinter. Da fehlt noch eine Menge Grundwissen. Obige Fehlermeldung in Verbindung mit der Doku ist eindeutig:
> 
> SessionScoped (Java EE 6 )



Eindeutig finde ich es nicht. Was genau meinst du?

Das war ja die Frage, ob es überhaupt eine Möglichkeit mit RMI gibt den SessionScoped zu verwenden oder ob ich die Transportschicht auf HTTP umstellen muss.
Oder ob es eine ganz andere Möglichkeit mit RMI gibt ???:L

Deshalb versuche ich grad das hier
EJB, JMS and JNDI over HTTP with Unified Invoker | JBoss Community


----------



## FArt (29. Apr 2011)

SirWayne hat gesagt.:


> Eindeutig finde ich es nicht. Was genau meinst du?
> 
> Das war ja die Frage, ob es überhaupt eine Möglichkeit mit RMI gibt den SessionScoped zu verwenden oder ob ich die Transportschicht auf HTTP umstellen muss.
> Oder ob es eine ganz andere Möglichkeit mit RMI gibt ???:L
> ...



Das ist Käse. Es liegt nicht an der Transportschicht, sondern am Kontext des Calls. Die Doku sagt doch eindeutig


> The session scope is active: during the service() method of any servlet in the web application, during the doFilter() method of any servlet filter and when the container calls any HttpSessionListener, AsyncListener or ServletRequestListener.



Bei einem einfachen Beancall hast du kein Servlet, egal über welches Transportprotokoll der Call kommt. Wie schon gesagt, da fehlt dir die Theorie bzgl. EJBs und Webapplikationen (Servlets), deren Unterschiede, Gemeinsamkeiten und das Zusammenspiel.

Eine andere Art der EJB Invocation zu wählen ist nur sinnvoll, wenn z.B: die Infrastruktur gegen RMI spricht, denn gerade HTTP wird langsamer sein als RMI.


----------



## Gast2 (29. Apr 2011)

FArt hat gesagt.:


> Das ist Käse. Es liegt nicht an der Transportschicht, sondern am Kontext des Calls. Die Doku sagt doch eindeutig
> 
> 
> Bei einem einfachen Beancall hast du kein Servlet, egal über welches Transportprotokoll der Call kommt. Wie schon gesagt, da fehlt dir die Theorie bzgl. EJBs und Webapplikationen (Servlets), deren Unterschiede, Gemeinsamkeiten und das Zusammenspiel.
> ...



Okay welche Möglichkeit habe ich dann remote in dem Fall RMI ein Bean einer Session zuzuordnen.

Wie gesagt meine Idee wäre gewesen den Call über HTTP zu machen und mit dem EJB3InvokerServlet weiterzuleiten? Würde das nicht gehen?


----------



## Gast2 (29. Apr 2011)

FArt hat gesagt.:


> Das ist ein seltsames Konstrukt, dessen Sinn sich mir nicht erschließt. Dennoch würde es funktionieren. Jedoch nur EJBs im Servletcall können den Scope verwenden, nicht ein EJB davor.


Ja wie gesagt darum wohl doch eher über Webservice gehen, dann solltem die Probleme weg sein?!?!



FArt hat gesagt.:


> Was ist eigenlich deine Anforderung? Denn ein SFSB hält ja auch einen Kontext, diesen über seine Lebensdauer, die der Client (aktiv) bestimmt bzw. über den Timeout des SFSB. Warum muss es der Servletkontext sein?



Ich beschreib nochmal kurz die Anforderung mit JSF + SessionScoped war das kein Problem jetzt mit einem Richclient kamen diese Probleme:
User1 meldet sich an, der sollte eine Session haben solange er angemeldet ist, weil die Daten bei manchen Aufrufen ausgewertet werden.
User2 meldet sich an, auch diese Daten sollen eindeutig an eine Session gebunden sein.

Jetzt kann ich bei einem RichClient die UserDaten bei jedem Remote Aufurf mit schicken was ziemlich bäh wäre.

Oder eben eine Möglichkeit finden dass die UserDatem in einer long running session auf dem Server bleiben und bei jedem Aufruf zugeordnet werden können.

Ist die Anforderung klar oder verständlicher?^^




FArt hat gesagt.:


> Dir fehlt die Theorie hinter Webapplikationen, EJBs und deren Zusammenspiel in einem AS


Ja so tiefgreifend war ich noch nicht drin, aber was ich grad so lese verstehe ich langsam die Probleme, auch wenn ich mir nicht vorstellen kann, dass ich der einzige bin der mit einem RichClient solche Probleme hat. Darum hoff ich noch irgendwo auf eine Lösung zu stoßen =)


----------



## FArt (29. Apr 2011)

SirWayne hat gesagt.:


> Okay welche Möglichkeit habe ich dann remote in dem Fall RMI ein Bean einer Session zuzuordnen.


Stateful Session Bean


----------



## Gast2 (29. Apr 2011)

FArt hat gesagt.:


> Stateful Session Bean



Ja aber ich bekomm ja bei jedem RMI aufruf eine neue Session ID? Also ist das Bean ja nur für einen Aufruf eindeutig. Wie in dem Beispiel oben.

EDIT: Ich mach mal kurz 2 zip Dateien(Server/Client) vielleicht ist das leichter zum Anschauen


----------



## FArt (29. Apr 2011)

SirWayne hat gesagt.:


> Ja aber ich bekomm ja bei jedem RMI aufruf eine neue Session ID? Also ist das Bean ja nur für einen Aufruf eindeutig. Wie in dem Beispiel oben



Wenn du jedes mal ein neues Bean erzeugst, ja. Aber wenn jeder Client mit seinem SFSB arbeitet, dann nein. Zur Erinnerung: fehlendes Konzeptverständnis! Und das hat nichts mit RMI zu tun. Dem Beanentwickler ist die Transportschicht in der Regel egal!



SirWayne hat gesagt.:


> Ja so tiefgreifend war ich noch nicht drin, aber was ich grad so lese verstehe ich langsam die Probleme, auch wenn ich mir nicht vorstellen kann, dass ich der einzige bin der mit einem RichClient solche Probleme hat. Darum hoff ich noch irgendwo auf eine Lösung zu stoßen =)


1D10T Fehler hat in der Regel jeder, der ohne Enteprisekenntnisse loslegt. Ohne Kenntnis über die Konzepte der Technologien versucht man gerne Lösungen zu produzieren, die man kennt und versteht, aber die passen dann eben nicht in die Enterprisewelt.

tutorial stateful session bean - Google-Suche


----------



## Gast2 (29. Apr 2011)

FArt hat gesagt.:


> Wenn du jedes mal ein neues Bean erzeugst, ja. Aber wenn jeder Client mit seinem SFSB arbeitet, dann nein. Zur Erinnerung: fehlendes Konzeptverständnis! Und das hat nichts mit RMI zu tun. Dem Beanentwickler ist die Transportschicht in der Regel egal!


Jo das versuch ich darum ist meine Bean ja Statefull, nur wenn ich debuge ist die Session-ID IMMER anders und die Bean ist dann auch neu (logischwereise). Siehe Beispiel vielleicht versteht dann was ich meine.




FArt hat gesagt.:


> 1D10T Fehler hat in der Regel jeder, der ohne Enteprisekenntnisse loslegt. Ohne Kenntnis über die Konzepte der Technologien versucht man gerne Lösungen zu produzieren, die man kennt und versteht, aber die passen dann eben nicht in die Enterprisewelt.
> 
> tutorial stateful session bean - Google-Suche



Kenn ich alle schon und hab auch alle durch gemacht. Ich glaub es liegt an dem Injecten eines 2ten Beans und dass dieses dem Service falsch injected wird. Wie gesagt im Beispiel unten wird mein Problem deutlich da das UserBean immer neu erzeugt wird, deshalb NPE.

EDIT: Wie gesagt ich vermute das Zusammenspiel der 2 RemoteService mit der einen Stateful Bean ist das Problem, das klappt nicht richtig.


----------



## Gast2 (29. Apr 2011)

Mhm ist das Problem jetzt zu einfach/schwer oder zu unverständlich ?


----------



## FArt (30. Apr 2011)

SirWayne hat gesagt.:


> Mhm ist das Problem jetzt zu einfach/schwer oder zu unverständlich ?



Weder noch. Ich persönlich habe nur gerade keine Zeit für dich.
Ausserdem würde ich dir gerne etwas Zeit lassen, das Problem ein wenig selber zu analysieren.



> Kenn ich alle schon und hab auch alle durch gemacht. Ich glaub es liegt an dem Injecten eines 2ten Beans und dass dieses dem Service falsch injected wird. Wie gesagt im Beispiel unten wird mein Problem deutlich da das UserBean immer neu erzeugt wird, deshalb NPE.


Das hört sich nach einer sinnvollen Vermutung an, wie deine vorherige auch schon. Die solltest du erst mal verifizieren und danach über Spec und Doku herausfinden, warum das so ist. Wichtig dabei: wie funktionieren SFSB, welchen Lebenszyklus haben sie, wie funktioniert DI an dieser Stelle...


----------



## Gast2 (30. Apr 2011)

FArt hat gesagt.:


> Das hört sich nach einer sinnvollen Vermutung an, wie deine vorherige auch schon. Die solltest du erst mal verifizieren und danach über Spec und Doku herausfinden, warum das so ist. Wichtig dabei: wie funktionieren SFSB, welchen Lebenszyklus haben sie, wie funktioniert DI an dieser Stelle...



Alles schon durchgeschaut 2 Tage lang sonst würde ich nicht ein ganzes Bsp. hier rein posten und fragen was mein Denkfehler ist oder ob es einfach nicht geht und ich einen anderen Weg gehen muss ...
Die ganzen Beispiele und Tutorials mit SFSB habe ich durchgemacht, dass ist auch alles kein Problem mit einem Bean. Wie gesagt das Problem liegt daran, dass der 2te Service aufruft nicht das gleiche Bean bekommt, warum konnte ich durch die Spec nicht rausfinden und kann es mir auch logisch nicht erklären.


----------



## FArt (30. Apr 2011)

Mit einer selbstgestrickten Authorisierung über ein SFSB wirst du keinen Blumentopf gewinnen: der Ansatz ist ... höflich ausgedrückt ... suboptimal.
Ja, mit einem Webservice mag es (technisch gesehen) "funktionieren". Aber auch hier gilt: warum das Rad neu erfinden, und dann auch noch dreieckig?

Lösung: nutze JAAS und sichere dein fachliches Bean damit ab. Was für ein Zufall, dass JBoss bereits mit allem daherkommt was du benötigst, inklusive Beispielen und einfachen Loginmodulen (Properties, Datenbank, ...).

Zu deiner Frage: 
inject stateful sessionbean - Google-Suche

Weitere Fragen, die du dir stellen könntest:
Wie viel Sinn macht die Annotation @Named ohne Namen?
Was ist der Unterschied zwischen der Annotation @Inject und @EJB?


----------



## Gast2 (2. Mai 2011)

FArt hat gesagt.:


> Mit einer selbstgestrickten Authorisierung über ein SFSB wirst du keinen Blumentopf gewinnen: der Ansatz ist ... höflich ausgedrückt ... suboptimal.
> Ja, mit einem Webservice mag es (technisch gesehen) "funktionieren". Aber auch hier gilt: warum das Rad neu erfinden, und dann auch noch dreieckig?
> 
> Lösung: nutze JAAS und sichere dein fachliches Bean damit ab. Was für ein Zufall, dass JBoss bereits mit allem daherkommt was du benötigst, inklusive Beispielen und einfachen Loginmodulen (Properties, Datenbank, ...).


Es geht nicht um die Authorisierung , das war nur ein Beispiel ich brauche einfach einige Daten in einem Stateful Bean .



FArt hat gesagt.:


> Wie viel Sinn macht die Annotation @Named ohne Namen?


Klar hat Sie sinn gemacht wo ich JSF verwendet habe, warum soll Sie keinen SInn machen?

EDIT: Also laut diesem Artikel ist sowas nicht möglich
java - Possible to inject same stateful session bean instance into multiple other session beans? - Stack Overflow


----------



## Gast2 (2. Mai 2011)

Was ich auch nicht ganz verstehe ist, dass ich nach 2 lookups hintereinander 2 unterschiedliche Instanzen habe von dem Service habe das darf doch nicht sein wenn das Bean stateful ist :bahnhof:... 

```
MyService myService = context.lookup("myService");
MyService myService1 = context.lookup("myService");
```


----------



## FArt (2. Mai 2011)

SirWayne hat gesagt.:


> Was ich auch nicht ganz verstehe ist, dass ich nach 2 lookups hintereinander 2 unterschiedliche Instanzen habe von dem Service habe das darf doch nicht sein wenn das Bean stateful ist :bahnhof:...
> 
> ```
> MyService myService = context.lookup("myService");
> ...



Doch, genau dieses Verhalten is spec-compliant. Noch mal nachlesen: Lebenszyklus SFSB!!!
Der Name beim Lookup gibt nicht die Instanz an, sondern den Beantyp. myService und myService1 sind nun zwei unterschiedliche Stubs auf zwei Instanzen (Session). Calls auf dem gleichen Stub landen in der gleichen Session. Aber auch das muss nicht das selbe Java-Objekt auf Serverseite sein, dabei geht es nur um den internen Zustand! Theoretisch können Objektinstanzen zwischen aktiven Sessions gepoolt werden (so lange der interne Zustand gesichert und wieder hergestellt wird) oder eine Session kann (nach längerer Inaktivität) passiviert und bei Bedarf wieder aktiviert werden.

WICHTIG! WICHTIG! 
Dir fehlt Basiswissen!!!!!!!!!

Auch wenn du sagst, das mit dem Login wäre nur ein Beispiel. Was auch immer du gerade vor hast, das geht auch ohne diesen seltsamen Trick, nämlich mit einer einfachen SFSB!!!!


----------



## Gast2 (2. Mai 2011)

FArt hat gesagt.:


> Doch, genau dieses Verhalten is spec-compliant. Noch mal nachlesen: Lebenszyklus SFSB!!!


naja genau das soll nicht passieren!!! Die haben 2 unterschiedliche SessionIds auf Serverseite und dadurch auch 2 unterschiedliche Beans auf Servserseite und das soll nicht sein.

The Lifecycles of Enterprise Beans - The Java EE 6 Tutorial

Außerdem 
	
	
	
	





```
The state of an object consists of the values of its instance variables. In a stateful session bean, the instance variables represent the state of a unique client/bean session. Because the client interacts (“talks”) with its bean, this state is often called the conversational state.
```

mhm unique ist es aber nicht.



FArt hat gesagt.:


> WICHTIG! WICHTIG!
> Dir fehlt Basiswissen!!!!!!!!!
> 
> Auch wenn du sagst, das mit dem Login wäre nur ein Beispiel. Was auch immer du gerade vor hast, das geht auch ohne diesen seltsamen Trick, nämlich mit einer einfachen SFSB!!!!



lol was für ein trick denn?ganz normales di was ich mache.:bahnhof:

Da ist doch gleiche Problem und da ist nur ein Workarround mit ThreadLocal und sowas ist ziemlich unschön, was hat das mit BASISWISSEN zu tun?
java - Possible to inject same stateful session bean instance into multiple other session beans? - Stack Overflow

Beispiel einmal angeschaut und ausgeführt?  Wenn es so einfach ist hättest du die Lösung schon lang schreiben können, aber a) entweder verstehst du das problem gar nicht oder b) hast selber kein plan wie das problem mit DI zu lösen ist.


----------



## FArt (2. Mai 2011)

SirWayne hat gesagt.:


> naja genau das soll nicht passieren!!! Die haben 2 unterschiedliche SessionIds auf Serverseite und dadurch auch 2 unterschiedliche Beans auf Servserseite und das soll nicht sein.
> 
> 
> 
> ...



Ich habe mir dein Beispiel angeschaut. Ausführen musste ich es nicht, ich habe es gerade noch so verstanden. Ich habe dann auch verstanden, dass das alles ein typischer 1D10T-Fehler ist.

Und trotzdem: ja, du hast mich ertappt. Ich habe leider keine Ahnung wie das mit DI funktionieren soll. Da reihe ich mich somit in die Grupper der Stümper ein, die JSR 220 erfunden haben, die haben nämlich auch keine Ahnung davon. Und das liegt nicht daran, dass dieses Szeanrio so nicht funktioneren kann und auch nicht muss. Es liegt daran, dass ich zu blöd bin dir das begreiflich zu machen.

Tut mir leid, dass du deine Zeit mit mir verschwendet hast. Viel Erfolg bei deiner Lösung.
Letzter Tipp: lasse deine Architektur mal von einem Software-Architekten reviewen, der Erfahrung mit Enterpriseumgebungen hat.


----------



## Gast2 (2. Mai 2011)

FArt hat gesagt.:


> Ich habe mir dein Beispiel angeschaut. Ausführen musste ich es nicht, ich habe es gerade noch so verstanden. Ich habe dann auch verstanden, dass das alles ein typischer 1D10T-Fehler ist.
> 
> 
> > Freut mich dass du ihn erkannt hast.
> ...


----------



## Gast2 (2. Mai 2011)

Ist anscheinend gewollt, dass eine neue Session gibt.

Enterprise JavaBeans 3.0 - Google Bücher

**Every time you look up a stateful session bean in JNDI, a new session is created.

EJB3: Session Beans | Ranjan Kumar


----------



## FArt (2. Mai 2011)

SirWayne hat gesagt.:


> Ist anscheinend gewollt, dass eine neue Session gibt.
> 
> Enterprise JavaBeans 3.0 - Google Bücher
> 
> ...



Na also. Das nennt man (wie schon erwähnt) specification compliant, also konform nach der Spezifikation. Oder auf deutsch: das ist so gewollt 

In der JSR steht zwar nicht explizit drin, dass sich SFSB beim injizieren so verhalten, aber dort steht meines Wissens sinngemäß, dass die Annotation @EJB einem Lookup gleich kommt. Somit ist das eine neue Session. Dazu muss man wiederum wissen, dass der Lookup eine neue Session hervorzaubert, was auch in der Spec oder in dem verlinkten Buch steht.

Jetzt kommen wir wieder zum Ursprung zurück: dein Konstrukt kann so nicht funktionieren, auch wenn es zufällig über den Servletkontext geklappt hat. Somit musst du für das eigentliche Problem eine Lösung finden. Somit stellt sich jetzt die Frage, warum du das so benötigst. Im Falle einer Authentifizierung  würde man das regulär über JAAS lösen. Was hast du vor, was so aussieht wie Authentifizierung aber keine ist?


----------



## Gast2 (3. Mai 2011)

FArt hat gesagt.:


> Na also. Das nennt man (wie schon erwähnt) specification compliant, also konform nach der Spezifikation. Oder auf deutsch: das ist so gewollt


Nur weil es so gewollt ist muss ich den Sinn dahinter nicht verstehen =). Ich mein was bringt mir ein Stateful Bean wenn seine Daten nicht speichert. So kann man kein Stateful Bean in ein anderes injecten :bahnhof:. Also bringt es realtiv wenig.
Soviel ich weiß ging sowas mit Spring.



FArt hat gesagt.:


> In der JSR steht zwar nicht explizit drin, dass sich SFSB beim injizieren so verhalten, aber dort steht meines Wissens sinngemäß, dass die Annotation @EJB einem Lookup gleich kommt. Somit ist das eine neue Session. Dazu muss man wiederum wissen, dass der Lookup eine neue Session hervorzaubert, was auch in der Spec oder in dem verlinkten Buch steht.


In der Spec habe ich nichts gefunden dazu, dass eine neue Session kriert wird. Wie gesagt ich empfinde es sogar als suboptimal.



FArt hat gesagt.:


> Jetzt kommen wir wieder zum Ursprung zurück: dein Konstrukt kann so nicht funktionieren, auch wenn es zufällig über den Servletkontext geklappt hat.


Warum zufällig? Mit dem SessionScoped hat alles so geklappt wie ich es erwartet hätte wie mit Spring halt =)




FArt hat gesagt.:


> Somit musst du für das eigentliche Problem eine Lösung finden. Somit stellt sich jetzt die Frage, warum du das so benötigst. Im Falle einer Authentifizierung  würde man das regulär über JAAS lösen. Was hast du vor, was so aussieht wie Authentifizierung aber keine ist?



Zurzeit gibt es für jeden User einen Long running session die sich erst wieder schließt wenn der User sich am Rich Client abmeldet. Es gibt also ein SessionBean für jeden Client, welches sehr viele Daten und Properties hält, abhängig von dem angemeldeten User. Einige davon werden beim krieren von Abfragen benötigt.
Darum wollte ich eine Bean die sich an die Session koppelt, ich dachte eben an SFSB und die ich dann in die DAO's injecten kann. Da die DAO's auch SFSB sind, wegen PersistenceContextType.EXTENDED.

Verständlich ?


----------



## FArt (3. Mai 2011)

Nun ja. Ich finde die Spec an der Stelle schon sinnvoll, denn so wird der Lebenszyklus des zweiten SFSB an den des ersten gebunden und muss nicht explizit verwaltet werden, da ja in der Regel diese ja zusammenhänge.
Ein Prinzip ist es auch, dass eine Sesssion gegenüber einem Client (als Rolle) gilt. In deinem Fall erstellt ein Client das Bean und ein anderes soll es benutzen. Das widerspricht ein wenig dem Sinn. Es gibt zwar die Möglichkeit, ein SFSB weiter zu geben (über das Beanhandle), aber auch dann sind konkurrierende Zugriffe darauf laut Spec verboten.

Somit missbrauchst du hier also eigentlich ein SFSB um etwas bestimmtes zu erreichen, wofür SFSBs nicht gedacht sind.

Über ein Servlet ist das wieder etwas anderes. Im Prinzip finde ich eher dies als suboptimales Feature. Da das immer wahren Leben aber sehr praktisch sein kann, wurde es wohl aufgenommen. Hier muss man zwei verschiedene Spezfikationen (und zwei unterschiedliche Lebenszyklen mit ihren Kontexten) verbinden: die der Servletsession und die eines SFSB. Ohne diese Servletsesssion macht aber auch die von dir ursprünglich benutzte Annotation keinen Sinn.

Wie sollte man also dein Problem lösen?
Man könnte selber eine Art Session pflegen. Dieser zentrale Service (z.B. ein Singleton Bean) kann über einen Schlüssel (User und/oder evtl. eine Sessionid) die kontextabhängigen Daten halten.
Auf die Frage: und wie komme ich an allen möglichen Stellen an die Daten gibt es zwei Antworten: eigentlich nicht, denn wenn diese Daten so verteilt benötigt werden ist das wohl ein suboptimales Design. Die Frage ist also: ist das wirklich so nötig oder gibt es da eine bessere Lösung? 
Der Container bedient sich für solche Daten gerne einer anderen Technik: der Kontext über einen Call ist der laufende Thread. Somit können am Anfang des Calls die Daten mit dem Thread über einen ThreadLocal verbunden werden. Nach dem Ende des Calls müssen sie natürlich wieder vom Thread abgehängt werden, da der Thread höchswahrscheinlich in Kürze für einen anderen Call u.U. eines anderen Users verwendet wird. Die Verknüpfung würde man über die Authentifizierung des Users realisieren. Denkbar wäre hier ein Beaninterceptor über die Businessmethoden.

P.S.: ... oder die Daten in die DB legen oder ...

Die Session für alle mögliche Daten zu verwenden und überall zu injizieren ist ein bekannes Antipattern, auch aus der Javawelt: das böse Singleton.

Die echte Lösung also: Authentifizierung des Users über JAAS und dann abspeichern der kontextabhängigen Daten über den User, evtl mit Sessionbezug (SFSB).


----------



## Gast2 (3. Mai 2011)

FArt hat gesagt.:


> Nun ja. Ich finde die Spec an der Stelle schon sinnvoll, denn so wird der Lebenszyklus des zweiten SFSB an den des ersten gebunden und muss nicht explizit verwaltet werden, da ja in der Regel diese ja zusammenhänge.


Ja aber sobald ein 3tes SFSB kommt und sich ein 1 SFSB teilen will, haben beide immer unterschiedliche Instanzen, da ja immer ein neuer lookup und somit eine neues Session kriert hat, obwohl der Aufruf vom gleichen Client kommt. Den Sinn habe ich nich ganz verstanden.


FArt hat gesagt.:


> Somit missbrauchst du hier also eigentlich ein SFSB um etwas bestimmtes zu erreichen, wofür SFSBs nicht gedacht sind.


Ja das stimmt mit dem Sinn von SFSBs komme ich noch nicht so ganz klar.
Ein SFSBs ist zum Beispiel ein Warenkorb, so kann der Warenkrob weitere SFSBs injecten und verwaltet diese. Aber die SFSBs, die von dem Warenkorb verwaltet werden, kann kein anderes Bean verwenden. Also sind die injecteten SFSBs nur für den Warenkorb gültig.



FArt hat gesagt.:


> Über ein Servlet ist das wieder etwas anderes. Im Prinzip finde ich eher dies als suboptimales Feature. Da das immer wahren Leben aber sehr praktisch sein kann, wurde es wohl aufgenommen. Hier muss man zwei verschiedene Spezfikationen (und zwei unterschiedliche Lebenszyklen mit ihren Kontexten) verbinden: die der Servletsession und die eines SFSB. Ohne diese Servletsesssion macht aber auch die von dir ursprünglich benutzte Annotation keinen Sinn.


Ja ich fands sehr praktisch und intuitiv =). Ja darum wollte ich urprünglich über ein HTTP-Servlet gehen.



FArt hat gesagt.:


> Der Container bedient sich für solche Daten gerne einer anderen Technik: der Kontext über einen Call ist der laufende Thread. Somit können am Anfang des Calls die Daten mit dem Thread über einen ThreadLocal verbunden werden. Nach dem Ende des Calls müssen sie natürlich wieder vom Thread abgehängt werden, da der Thread höchswahrscheinlich in Kürze für einen anderen Call u.U. eines anderen Users verwendet wird. Die Verknüpfung würde man über die Authentifizierung des Users realisieren. Denkbar wäre hier ein Beaninterceptor über die Businessmethoden.


Ja die Idee habe ich oben schon mal angedeutet und wollten wir heut mal versuchen, da es gerade so ähnlich gelöst ist, aber davon wollten wir ja eigentlich weg kommen 



FArt hat gesagt.:


> Die echte Lösung also: Authentifizierung des Users über JAAS und dann abspeichern der kontextabhängigen Daten über den User, evtl mit Sessionbezug (SFSB).


Ja das ist meine Frage wie speicher ich Daten kontextabhängig, so dass ich diese in den DAO oder Services dann verwenden kann? Evtl. kleines Beispiel oder ein Tutorial?


----------



## FArt (3. Mai 2011)

Nun, die Stichworte hatte ich im Prinzip alle schon erwähnt.

Eine relativ einfache, wenn auch nicht die beste Lösung (ich gehe immer noch davon aus, dass ihr mit einem anderen Design diese Anforderung in der Form gar nicht hättet):
Benutze einen Service oder oder Singleton Bean. Dort wird zu jedem User der Kontext gehalten. Bei der Erstellung einer Session (ein SFSB) wird der Kontext angelegt, beim Löschen der Session wird der Kontext gelöscht, d.h. die Sessionbean regelt auch den Lebenszyklus des Kontext. Der User authentifiziert sich mit JAAS und über EJBContext (Java EE 6 ) bekommst du immer den aktuellen User in einem Bean.
Achtung: in dem Fall haben User und Session eine 1:1 Beziehung. Es bedarf erhöhter Verwaltung, wenn der Benutzer mehrere Session gleichzeitig haben könnte.

Gute Suchbegriffe für Google: contextual data ejb


----------



## Gast2 (3. Mai 2011)

FArt hat gesagt.:


> Nun, die Stichworte hatte ich im Prinzip alle schon erwähnt.
> 
> Eine relativ einfache, wenn auch nicht die beste Lösung (ich gehe immer noch davon aus, dass ihr mit einem anderen Design diese Anforderung in der Form gar nicht hättet):
> Benutze einen Service oder oder Singleton Bean. Dort wird zu jedem User der Kontext gehalten. Bei der Erstellung einer Session (ein SFSB) wird der Kontext angelegt, beim Löschen der Session wird der Kontext gelöscht, d.h. die Sessionbean regelt auch den Lebenszyklus des Kontext. Der User authentifiziert sich mit JAAS und über EJBContext (Java EE 6 ) bekommst du immer den aktuellen User in einem Bean.
> ...



Achso ja hab dich falsch verstanden: Dachte du meinstest damit eine andere Lösung.
Ja das Desgin kann nicht so einfach umgestellt werden, da die Anwendung ziemlich groß ist und das primäre Ziel ist es corba zu beseitigen .
Einen Versuch ist es mal Wert ist gerade eh nur ein Prototyp, wenn der Fall nicht klappt bliebt wohl nur den ThreadLocal. 
Das mit der 1:1 Beziehung könnte ein KO Kriterium sein. Mal schauen wie groß der Aufwand ist die Verwaltung selbst zu übernehmen.


----------



## FArt (3. Mai 2011)

Dann nimm den Sessionhandle als Schlüssel, nicht den User... schon kann ein User mehrere Sessionkontext halten...


----------



## Gast2 (3. Mai 2011)

FArt hat gesagt.:


> Dann nimm den Sessionhandle als Schlüssel, nicht den User... schon kann ein User mehrere Sessionkontext halten...



Ok, aber als 1. muss ich erstmal deine Lösung nachvollziehen und nachbauen^^


----------



## Gast2 (3. Mai 2011)

FArt hat gesagt.:


> Der User authentifiziert sich mit JAAS und über EJBContext (Java EE 6 ) bekommst du immer den aktuellen User in einem Bean.



Gibts dazu irgendwo ein Beispiel? Ich find nur die Doku.


----------



## TheDarkRose (3. Mai 2011)

Hallo, ich mische mich auch mal hier ein, da ich vor einen ähnlichen Problem stehe einen Application Rich Client zu einen JBoss AS zu programmieren.
Habe mir mal deinen Thread komplett durchgelesen, und dadurch schon ein paar Lösungen für mich gefunden 

Was mir noch für dich einfallen würde, das du nicht deine UserBean nicht in der AngeboteBean injectest, sondern alles SFSB's die auf deinen User verweisen in der UserBean injectest und über diese darauf zugreifst. Diese dürften dann in der gleichen Session laufen.

Oder wenn du ja vom Design her mit Usern arbeitest, solltest du überlegen auf JAAS umzusteigen. Damit hast du deinen Login, und kannst dann in deinen EJB's per EJBContext.getCallerPrincipal() auf den Usernamen und so zugreifen.
Vorallem solltest du dann soweit wie möglich Statefull SB vermeiden und so oft wie es geht Stateless verwenden. Z.b. ein Warenkorb müsste Statefull sein, eine AngeboteBean, kann wiederum Stateless sein, da sich diese die Daten ja meistens aus einer Datenbank holt. Der Username um die passenden Einträge in der DB zu finden, holt man sich ja dann per getCallerPrincipal();

Wo wir gerade beim Thema JAAS wären. Den Stoff den ich bis jetzt gefunden habe und angwendet, zeigt mir wie ich meine EJB's per Annotations absichere und Rollen verteile, wie ich eine Security Domain im JBoss anlege und wie sich diese in einer Web Application konfigurieren und nutzen lässt.
Aber wie mache ich einem Application Client diese Security Domain bekannt? JBossSX soll benutzt werden, also die Portabilität auf andere AS wäre vernachläsigbar. Die Doku dazu ist irgendwie kaum vorhanden.


----------



## Gast2 (4. Mai 2011)

TheDarkRose hat gesagt.:


> Was mir noch für dich einfallen würde, das du nicht deine UserBean nicht in der AngeboteBean injectest, sondern alles SFSB's die auf deinen User verweisen in der UserBean injectest und über diese darauf zugreifst. Diese dürften dann in der gleichen Session laufen.


Kommt eher nicht in Frage



TheDarkRose hat gesagt.:


> Oder wenn du ja vom Design her mit Usern arbeitest, solltest du überlegen auf JAAS umzusteigen. Damit hast du deinen Login, und kannst dann in deinen EJB's per EJBContext.getCallerPrincipal() auf den Usernamen und so zugreifen.
> Vorallem solltest du dann soweit wie möglich Statefull SB vermeiden und so oft wie es geht Stateless verwenden. Z.b. ein Warenkorb müsste Statefull sein, eine AngeboteBean, kann wiederum Stateless sein, da sich diese die Daten ja meistens aus einer Datenbank holt. Der Username um die passenden Einträge in der DB zu finden, holt man sich ja dann per getCallerPrincipal();


SBFS können auch nicht vermieden werden wegen dem PersistenceContext.

Ansonsten versuche ich auch noch gerade rauszfinden, welche Files ich auf dem Client benötige und welche auf dem Server um das JAAS Modul einzuführen.
SecurityAssociation and ClientLoginModule authentication not | PicketBox | JBoss Community

Also ich bin noch ein bischen verwirrt ob ich den SecruityClient verwenden musst oder den LoginContext. Wenn ich es richtig verstanden habe ist der LoginContext dafür da wenn der client in der gleichen Vm ist. Und über den SecruityClient finde ich nichts.
http://docs.jboss.org/jbosssecurity/docs/6.0/security_guide/html/The_JBoss_Security_Extension_Architecture.html#The_JBoss_Security_Extension_Architecture-The_relationship_between_the_security_domain_component_deployment_descriptor_value_the_component_container_and_the_JaasSecurityManager.


----------



## TheDarkRose (4. Mai 2011)

SirWayne hat gesagt.:


> Ansonsten versuche ich auch noch gerade rauszfinden, welche Files ich auf dem Client benötige und welche auf dem Server um das JAAS Modul einzuführen.
> SecurityAssociation and ClientLoginModule authentication not | PicketBox | JBoss Community



Also im JBoss selber musst du in der login-config.xml mal deine SecurityDomain erstellen, mit dem passenden LoginModul (Ldap, JDBC, whatsoever) CreateASimpleSecurityDomainForJBossSX | JBoss Community

In dem EJB Project ist ja eine ejb-jar.xml vorhanden. Zusätzlich muss noch eine jboss.xml erstellt werden. Dort sind dann deine EJB's und Methoden abzusichern. Chapter 1. J2EE Declarative Security Overview

Wie es nun auf den Client aussieht, ist ne andere Frage. Wie in Chapter 4. The JBoss Security Extension Architecture beschrieben, kann man auf der Client Seite das ClientLoginModule verwenden um die Principals an das EJB zu senden, auf der Serverseite findet dann die Authentifizierung statt. Aber man bekommt erst eine Exception, wenn man versucht auf eine gesicherte Bean zuzugreifen und nicht schon bei LoginContext.login(); Hab leider auch noch nicht rausgefunden wie man JBossSX transparent in einen Application Client einbindet.


----------



## Gast2 (4. Mai 2011)

Ja ich versuche grad das aus der FAQ zu machen.
SecurityFAQ | JBoss AS | JBoss Community

Hab eine auth.conf in der META-INF angelegt

```
clientlogin {
   // jBoss LoginModule
   org.jboss.security.ClientLoginModule  required
   ;
};
```
Und dann das hier versucht, aber die Datei wird nicht gefunden, selbst wenn Sie in den src Ordner lege

```
SecurityClient client = SecurityClientFactory.getSecurityClient();
        client.setJAAS("clientlogin", new Client.MyCallbackHandler());
        client.login();
```


```
Exception in thread "main" java.lang.SecurityException: Anmeldekonfiguration kann nicht gefunden werden.
	at com.sun.security.auth.login.ConfigFile.<init>(ConfigFile.java:93)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
	at java.lang.Class.newInstance0(Class.java:355)
	at java.lang.Class.newInstance(Class.java:308)
	at javax.security.auth.login.Configuration$3.run(Configuration.java:247)
	at java.security.AccessController.doPrivileged(Native Method)
	at javax.security.auth.login.Configuration.getConfiguration(Configuration.java:242)
	at javax.security.auth.login.LoginContext$1.run(LoginContext.java:237)
	at java.security.AccessController.doPrivileged(Native Method)
	at javax.security.auth.login.LoginContext.init(LoginContext.java:234)
	at javax.security.auth.login.LoginContext.<init>(LoginContext.java:403)
	at org.jboss.security.client.JBossSecurityClient.performJAASLogin(JBossSecurityClient.java:64)
	at org.jboss.security.client.SecurityClient.login(SecurityClient.java:69)
	at main.Client.main(Client.java:47)
Caused by: java.io.IOException: Anmeldekonfiguration kann nicht gefunden werden.
	at com.sun.security.auth.login.ConfigFile.init(ConfigFile.java:250)
	at com.sun.security.auth.login.ConfigFile.<init>(ConfigFile.java:91)
	... 16 more
```

Ich muss erstmal keine EJB absichern es soll einfach ein User sich anmelden und in das Bean in den EJBContext. 
Später ist das LoginModul auch nicht schwer es muss nur überprüft werden ob der User in der DB vorhanden ist.


----------



## TheDarkRose (4. Mai 2011)

Hmm, SecurityClient verwende ich gar nicht. Nehm dazu den LoginContext

```
LoginContext lc = new LoginContext("clientlogin", new AppCallbackHandler("user", "pass"));
lc.login();
```
,


Edit: Ich glaub ich hab was gutes gefunden. Man verwendet für den InitialContext die LoginInitialContextFactory | JBoss Community
Dort gibt man beim Environment zusätzlich den User, das Password und die SecurityDomain, die am Server definiert wurde an. Wen man nun den InitialContext erzeug, wird zuerst ein JAAS Login am Server ausgeführt (so wie es ja gewünscht ist) und dann erst der InitialContext erzeugt. Sollte der Login nicht erfolgreich sein, bekommt man eine AuthenticationException.
org.jboss.security.jndi.LoginInitialContextFactory (Java2HTML)


----------



## Gast2 (4. Mai 2011)

Gleiches Problem wo hast du die config datei hingetan?


----------



## TheDarkRose (4. Mai 2011)

Die kannst du hintun wo du willst, muss diese aber über das Property java.security.auth.login.config angeben.
JAAS Login Configuration File


----------



## Gast2 (4. Mai 2011)

TheDarkRose hat gesagt.:


> Die kannst du hintun wo du willst, muss diese aber über das Property java.security.auth.login.config angeben.
> JAAS Login Configuration File



Argh stimmt hab ich eigentlich gelesen...



TheDarkRose hat gesagt.:


> In dem EJB Project ist ja eine ejb-jar.xml vorhanden. Zusätzlich muss noch eine jboss.xml erstellt werden. Dort sind dann deine EJB's und Methoden abzusichern. Chapter*1.*J2EE Declarative Security Overview


Ich hab keine ejb-jar.xml ich verwende ejb3.1, da benötige ich keine mehr.

Das mit der JBoss.xml habe ich nur nicht richtig durchschaut. Brauch ich eine jboss.xml oder reicht das web.xml aus?



TheDarkRose hat gesagt.:


> Hab leider auch noch nicht rausgefunden wie man JBossSX transparent in einen Application Client einbindet.



Ja ich hab jetzt nur mal den LoginContext aufgerufen.


----------



## TheDarkRose (4. Mai 2011)

SirWayne hat gesagt.:


> Ich hab keine ejb-jar.xml ich verwende ejb3.1, da benötige ich keine mehr.


Stimmt, da geht das ja mit Annotations.



SirWayne hat gesagt.:


> Das mit der JBoss.xml habe ich nur nicht richtig durchschaut. Brauch ich eine jboss.xml oder reicht das web.xml aus?



Diese muss in dem EJB Project liegen, wo du mindestens die Security Domain angibst die verwendet wird. Brauchst du auf jeden Fall wenn man es direkt per JAAS mit ClientLoginModule im AppClient versucht. Ich glaub bei der LoginInitialContextFactory (wie oben beschrieben) is das nicht mehr nötig, kann aber nicht schaden.
Chapter*3.*JBoss Security Model
[XML]<jboss>
    <security-domain>my-sec-dom</security-domain>
</jboss>[/XML]

eine web.xml brauchst du gar nicht, da hier ja keine WebApplication am Werk ist.



SirWayne hat gesagt.:


> Ja ich hab jetzt nur mal den LoginContext aufgerufen.



Ja, aber mit ClientLoginModule werden nur die Principals in ein Subject kopiert. Mehr macht das ja nicht. Die Serverseitige Authentifizierung findet ja erst beim ersten JNDI Lookup statt.


----------



## Gast2 (4. Mai 2011)

Hab dein Edit gar nicht gesehen hast du die Klasse schon gefunden in welchem jar die liegt bei ist sie in jbosssx-client.jar nicht enthalten.

Ok in der jbosssx-as-client.jar ist sie drin.


----------



## Gast2 (4. Mai 2011)

EDIT: Für remote client JndiLoginInitialContextFactory benutzen

Aber klappt auch nicht beim Context holen:
Erst wenn ich auf das Bean zugreife bekomme ich eine expection

```
Exception in thread "AWT-EventQueue-0" javax.ejb.EJBAccessException: Invalid User
	at org.jboss.ejb3.security.Ejb3AuthenticationInterceptorv2.invoke(Ejb3AuthenticationInterceptorv2.java:161)
	at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
```


----------



## TheDarkRose (4. Mai 2011)

Warum die JndiLoginInitialContextFactory?


----------



## Gast2 (4. Mai 2011)

TheDarkRose hat gesagt.:


> Warum die JndiLoginInitialContextFactory?



Weil er sonst mein Protokoll nicht findet... Steht ja unten extra für remote clients. Oder der Context.SECURITY_PROTOCOL gibt den domain auf dem Server an?


Bei LoginInitialContextFactory,bekomm ich auf den Client die Fehlermeldung

```
Caused by: javax.security.auth.login.LoginException: Für prototyp sind keine Anmeldemodule konfiguriert.
	at javax.security.auth.login.LoginContext.init(LoginContext.java:256)
	at javax.security.auth.login.LoginContext.<init>(LoginContext.java:403)
	at org.jboss.security.jndi.LoginInitialContextFactory.getInitialContext(LoginInitialContextFactory.java:84)
	... 50 more
```

login.config.xml
[XML]
    <application-policy name="prototyp">
          <authentication>
               <login-module 
                    code="org.jboss.security.auth.spi.UsersRolesLoginModule"
                    flag = "required">
                    <module-option
                         name="usersProperties">
                         props/prototyp-users.properties
                    </module-option>
                    <module-option
                         name="rolesProperties">
                         props/prototyp-roles.properties
                    </module-option>
               </login-module>
          </authentication>
     </application-policy>
[/XML]

Wie hast du es gemacht?


----------



## TheDarkRose (4. Mai 2011)

argh, der InitialContext wird ja auf dem Client ausgeführt. Also wird wieder ein JAAS Aufruf am Client hervorgerufen. Genau das was mir nicht brauchen. Denn JAAS auf clientseite ist unsicher durch die Konfigurierbarkeit, da jemand z.b. eine LdapExtLoginModule durch etwas anderes ersetzen könnte. Gut, da ja JAAS dann die Principals an den Server sendet, macht dieser ja auch noch seine Auth und die gefälschten Daten würden dann natürlich abgelehnt werden. Trotzdem nicht schön, wenn sich dem Hacker die Oberfläche so weit offenbart bis zum ersten EJB Inject. So mal ein bisschen Theorie nebenbei.

JndiLoginInitialContextFactory wär dann eh das richtige. Diese verknüpft die Principals mit der SecurityAssocation, welche dann bei jeden JNDI Lookup zu einen EJB mitgesendet werden sollte. Dann authentifiziert dich der Server jedes Mal.
Also sollte man direkt nach den erzeugen des InitialContext einen Lookup machen, und sei es nur auf eine Dummy EJB, um zu testen ob die Logindaten stimmen. Oder z.B. eine EJB die einem die Rollen zurückliefert, nach der man die Oberfläche aufbauen kann.

Edit: ich hab leider noch nichts von heute gemacht, da ich noch immer in der Arbeit sitze :noe:


----------



## Gast2 (4. Mai 2011)

Also vielleicht nochmal deutlicher:

Auf dem Server im login-config.xml habe ich den eintrag:
[XML]
    <authentication>
      <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
        flag="required"/>
    </authentication>
  </application-policy>

    <application-policy name="prototyp">
          <authentication>
               <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required">
                    <module-option name="usersProperties">props/prototyp-users.properties</module-option>
                    <module-option name="rolesProperties">props/prototyp-roles.properties</module-option>
               </login-module>
          </authentication>
     </application-policy>
[/XML]

dann die beiden properties files prototyp-users.properties:

```
admin=admin
```
props/prototyp-roles.properties

```
admin=Admin
```

Auf dem Client:

```
prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.security.jndi.LoginInitialContextFactory");
		prop.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
		prop.put(Context.PROVIDER_URL, "jnp://localhost:1099/");
		prop.put(Context.SECURITY_PROTOCOL, "prototyp");
		prop.put(Context.SECURITY_CREDENTIALS, "admin");
		prop.put(Context.SECURITY_PRINCIPAL, "admin");
		
//        InitialContext ctx = new InitialContext(prop);
//		JndiLoginInitialContextFactory initialContextFactory = new JndiLoginInitialContextFactory();
		LoginInitialContextFactory initialContextFactory = new LoginInitialContextFactory();
        // lookup the account manager bean
        Context context = initialContextFactory.getInitialContext(prop);
```

und das auth.config file, das soll ich nur die Authenfizierung an den Server weiter geben ?

```
prototyp {
   // jBoss LoginModule
   org.jboss.security.ClientLoginModule  required
   ;
};
```


So anmelden klappt greif ich auf das bean zu:
Bekomm ich ein invalid user
1. Frage warum ???:L
2. wenn ich einen falschen Benutzer mitgebe klappt die Anmeldung trotzdem dachte dann ist der context null :bahnhof:...

mhm


----------



## TheDarkRose (4. Mai 2011)

Eigentlich müsstest du eine AuthenticationException bekommen.

Quelltexte:
org.jboss.security.jndi.LoginInitialContextFactory (Java2HTML)
org.jboss.security.jndi.JndiLoginInitialContextFactory (Java2HTML)


Edit: ein LoginContext.login() klappt beim ClientLoginModule immer, da dieser nur die Principals in das Subject schreibt ohne Authentifizierung. Diese sollte dann am Server geschehen.


----------



## Gast2 (4. Mai 2011)

TheDarkRose hat gesagt.:


> argh, der InitialContext wird ja auf dem Client ausgeführt. Also wird wieder ein JAAS Aufruf am Client hervorgerufen. Genau das was mir nicht brauchen. Denn JAAS auf clientseite ist unsicher durch die Konfigurierbarkeit, da jemand z.b. eine LdapExtLoginModule durch etwas anderes ersetzen könnte. Gut, da ja JAAS dann die Principals an den Server sendet, macht dieser ja auch noch seine Auth und die gefälschten Daten würden dann natürlich abgelehnt werden. Trotzdem nicht schön, wenn sich dem Hacker die Oberfläche so weit offenbart bis zum ersten EJB Inject. So mal ein bisschen Theorie nebenbei.



Ja das habe ich ja im obigen Post mal versucht würde ich nicht so schlimm finden.




TheDarkRose hat gesagt.:


> JndiLoginInitialContextFactory wär dann eh das richtige. Diese verknüpft die Principals mit der SecurityAssocation, welche dann bei jeden JNDI Lookup zu einen EJB mitgesendet werden sollte. Dann authentifiziert dich der Server jedes Mal.
> Also sollte man direkt nach den erzeugen des InitialContext einen Lookup machen, und sei es nur auf eine Dummy EJB, um zu testen ob die Logindaten stimmen. Oder z.B. eine EJB die einem die Rollen zurückliefert, nach der man die Oberfläche aufbauen kann.



So dass habe ich auch mal versucht. Geleiche xml von oben auf dem Server

Client

```
prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.security.jndi.JndiLoginInitialContextFactory");
		prop.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
		prop.put(Context.PROVIDER_URL, "jnp://localhost:1099/");
		prop.put(Context.SECURITY_PROTOCOL, "prototyp");
		prop.put(Context.SECURITY_CREDENTIALS, "admin");
		prop.put(Context.SECURITY_PRINCIPAL, "admin");
		
		JndiLoginInitialContextFactory initialContextFactory = new JndiLoginInitialContextFactory();
        Context context = initialContextFactory.getInitialContext(prop);
```

Hat funktioniert. Wenn ich einen falschen User mitgebe beim ersten lookup 

```
Exception in thread "AWT-EventQueue-0" javax.ejb.EJBAccessException: Invalid User
```
:toll::toll:

So und nun nach langer Geburt , wie bekomme ich ein Bean mit den Session Infos in EJBContext

EDIT: Die jboss.xml braucht man auf jeden fall sonst werden die falschen user nicht erkannt!


----------



## TheDarkRose (4. Mai 2011)

Warum hast du da zusätzlich ein [c]new JndiLoginInitialContextFactory();[/c]. Eigentlich sollte [c]Context = new InitialContext(env);[/c] doch reichen? Denn der Konstruktor von InitialContext sollte zur Laufzeit die ContextFactory anhand der env Properties bestimmen und diese Factory aufrufen.

Edit: mhm, denn die jboss.xml bestimmt ja welche Security Domain nun verwendet wird.


----------



## Gast2 (4. Mai 2011)

TheDarkRose hat gesagt.:


> Warum hast du da zusätzlich ein [c]new JndiLoginInitialContextFactory();[/c]. Eigentlich sollte [c]Context = new InitialContext(env);[/c] doch reichen? Denn der Konstruktor von InitialContext sollte zur Laufzeit die ContextFactory anhand der env Properties bestimmen und diese Factory aufrufen.



Ja hast recht ist jetzt doppelt drin. naja irgenwie doof, dass man nicht beim login gleich eine exception bekommen kann, sondern erst beim 1. EJB aufruf.

aber meine @RolesAllowed("admin") klappt noch nicht damit sperr ich alles , mal schauen was da schief läuft.

Nun ja aber das ist mir nicht so wichtig, eher wie ich jetzt die Session infos in den EJBContext bekomme


----------



## TheDarkRose (4. Mai 2011)

Hmm, vl Case Sensitive?

wegen dem Context, füge mal folgendes Feld in deine EJB und versuch dann in einer Methode aufzrufen

```
@Resource SessionContext ctx;
```


----------



## Gast2 (4. Mai 2011)

TheDarkRose hat gesagt.:


> Hmm, vl Case Sensitive?


Nee schon probiert.



TheDarkRose hat gesagt.:


> wegen dem Context, füge mal folgendes Feld in deine EJB und versuch dann in einer Methode aufzrufen
> 
> ```
> @Resource SessionContext ctx;
> ```



Ja das hab ich gelesen...
Aber jetzt muss ich ein Singelton machen mit einer Map<Id?,MeinBean> mhm? Ich muss mal drüber schlafen


----------



## TheDarkRose (4. Mai 2011)

SirWayne hat gesagt.:


> Nee schon probiert.


Füge noch bei der class Definition ein [c]@DeclareRoles("Admin")[/c] hinzu.




SirWayne hat gesagt.:


> Aber jetzt muss ich ein Singelton machen mit einer Map<Id?,MeinBean> mhm? Ich muss mal drüber schlafen


Anderes unabhängiges Problem?


----------



## Gast2 (5. Mai 2011)

TheDarkRose hat gesagt.:


> Anderes unabhängiges Problem?



Nein das Ausgangsproblem, ich brauche eine Bean, die einige Informationen beinhaltet für jede Session


----------



## Gast2 (5. Mai 2011)

FArt hat gesagt.:


> Benutze einen Service oder oder Singleton Bean. Dort wird zu jedem User der Kontext gehalten. Bei der Erstellung einer Session (ein SFSB) wird der Kontext angelegt, beim Löschen der Session wird der Kontext gelöscht, d.h. die Sessionbean regelt auch den Lebenszyklus des Kontext. Der User authentifiziert sich mit JAAS und über EJBContext (Java EE 6 ) bekommst du immer den aktuellen User in einem Bean.



Könntest mit die Idee nochmal bischen genauer erklären?

Ich habe eine Singelton Bean z.B. SessionContainer mit einer Map<Id oder Oder,Kontext>.
Was genau ist Kontext meine eigene Bean mit meinen Infos oder der EJBContext bzw. SessionKontext?
Ist die Session Bean meine eigene Bean?



FArt hat gesagt.:


> Der User authentifiziert sich mit JAAS und über EJBContext (Java EE 6 ) bekommst du immer den aktuellen User in einem Bean.


ok mit 
	
	
	
	





```
@Resource private EJBContext context
```
 hole ich mit den Context und über 
	
	
	
	





```
context.getCallerPrincipal()
```
hole ich mir den User und darüber über mein Singelton die Session Infos? 

Kommt das so ungefähr hin?

Die Idee das ein User mehrer Session haben kann, war mir auch noch nicht so klar, aber erst mal klein anfangen , oder hast du meine dass ich mir selber eine eindeutige Session ID generieren lassen soll mit org.jboss.util.id.GUID?


----------



## FArt (5. Mai 2011)

Ja, so könnte ich mir das vorstellen.

Der Client erstellt eine Session (SFSB), authentifiziert sich gegenüber dem Server. Das SFSB kann das Singleton Bean injiziert bekommen. Dieses Bean hält die kontextabhängigen Daten, Schlüssel sind die Prinzipalinformationen (also der User). Das SFSB sollte über create und destroy die Lebensdauer des Kontextes steuern.
Wenn jetzt ein User mehrere Sessions gleichzeitig haben soll (mit unterschiedlichen Kontexten), könnte man die Prinzipalinformationen um eine auf Clientseite generierte ID erweitern, die dazu dient die Session zu identifizieren. Diese ID kann dann als Schlüssel verwendet werden.


----------



## Gast2 (5. Mai 2011)

FArt hat gesagt.:


> Der Client erstellt eine Session (SFSB), authentifiziert sich gegenüber dem Server.



Damit habe ich noch Probleme und woher ich jetzt die User Info genau bekomme.

Also mal was ich auf dem Server habe:


```
@Stateful
public class PricePilotSession {

	private Object uuid;
	@EJB
	private ContextContainer container;
	@Resource(mappedName="UUIDKeyGeneratorFactory")
	private KeyGeneratorFactory generatorFactory;	

	@PostConstruct
	public void create(){
		   KeyGenerator kg;
		try {
			kg = generatorFactory.getKeyGenerator();
			 uuid = kg.generateKey();
		} catch (Exception e) {
			e.printStackTrace();
		}
		container.addContext(uuid, new Context());
	}
	
	@PreDestroy
	public void destroy(){
		container.removeContext(uuid);
	}
}
```


```
public class Context {

	public String info;
	public String username;
//usw.
}
```


```
@Singleton
@Startup
public class ContextContainer {

	Map<Integer,Context> map = new HashMap<Integer, Context>();
	
}
```


```
@Stateful
public class AngebotRemoteServiceImpl implements AngebotRemoteService{

	@Override
	public Set<Angebot> getAngebote() {

                          // wie bekomme ich jetzt hier die Infos rein???
		return angebote;
	}
}
```

Client:


```
public void login(String name, char[] pwd) throws LoginException, NamingException  {
		prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.security.jndi.JndiLoginInitialContextFactory");
		prop.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
		prop.put(Context.PROVIDER_URL, "jnp://localhost:1099/");
		prop.put(Context.SECURITY_PROTOCOL, "prototyp");
		prop.put(Context.SECURITY_CREDENTIALS, pwd);
		prop.put(Context.SECURITY_PRINCIPAL, name);

                         Context context = new InitialContext(prop);
```

Mir fehlt jetzt die Sache wie ich die Infos in einen Service bekomme und woher ich jetzt die UserDaten nehme?
Und wenn ich auf Ressource zugreife bekomme ich auch noch ein lookup Errors =(.


```
Caused by: java.lang.NoSuchMethodError: javax.annotation.Resource.lookup()Ljava/lang/String;
```


----------



## FArt (6. Mai 2011)

Die Information bekommst du aus dem Principal. Natürlich brauchst du u.U. eine eigene Implementierung.

Ich habe mich mal etwas intensiver mit der JSR-299 beschäftigt und bin zu dem Schluss gekommen, dass es mittleweile wohl eine bessere Lösung gibt. Im Kapitel 6 (Scopes and Contexts) geht es auch um Kontexte, die so funktionieren wie hier gefordert. Im Prinzip gibt es schon eine fertige Implementierung für Webapplikationen. Man muss wohl aber (wenn ich das auf den ersten Blick recht verstanden habe) einen eigenen Context  verwenden bzw. dem Bean injecten, der von der Applikation gesteuert wird (im Falle der Webanwendung macht das das Servlet über seinen Session-Lifecycle).

JBoss 6 kommt mit Weld daher, der Referenzimplementierung. Wenn ich Zeit habe, werde ich mal einen PoC klöppeln (kann man immer mal brauchen).
Ich würde also empfehlen u.U. in diese Richtung weiter zu forschen. Mein "Ansatz" ist wohl altbacken, würde aber funktionieren. Der JSR-299 Context macht wohl auch nichts anderes, ist nur wesentlich angenehmer in der Verwendung.


----------



## TheDarkRose (6. Mai 2011)

@SirWayne
Kannst du mir mal deine EAR schicken, irgendwie hab ich Probleme das umzusetzen was wir hier diskutiert haben :bahnhof:


----------



## Gast2 (9. Mai 2011)

TheDarkRose hat gesagt.:


> @SirWayne
> Kannst du mir mal deine EAR schicken, irgendwie hab ich Probleme das umzusetzen was wir hier diskutiert haben :bahnhof:



Hier sind mal beide Projekte


----------



## Gast2 (9. Mai 2011)

FArt hat gesagt.:


> Die Information bekommst du aus dem Principal. Natürlich brauchst du u.U. eine eigene Implementierung.


Ja daran scheitert es gerade, ich weiß nich wo ich ansetzen muss. Mir fehlt der Startpunkt.



FArt hat gesagt.:


> Ich habe mich mal etwas intensiver mit der JSR-299 beschäftigt und bin zu dem Schluss gekommen, dass es mittleweile wohl eine bessere Lösung gibt. Im Kapitel 6 (Scopes and Contexts) geht es auch um Kontexte, die so funktionieren wie hier gefordert. Im Prinzip gibt es schon eine fertige Implementierung für Webapplikationen. Man muss wohl aber (wenn ich das auf den ersten Blick recht verstanden habe) einen eigenen Context  verwenden bzw. dem Bean injecten, der von der Applikation gesteuert wird (im Falle der Webanwendung macht das das Servlet über seinen Session-Lifecycle).



Okay schau ich da nochmal. Ja die fertige Implmentierung ist ja der SessionScope für Weapps, oder was meinst du?
Was meinst du mit Context eine EJBContext? Werd mir das Kapitel nochmal anschauen.

EDIT:
Meinst du Kapitel 5?
Chapter*5.*Scopes and contexts



> For example, if we have a session-scoped bean, CurrentUser, all beans that are called in the context of the same HttpSession will see the same instance of CurrentUser. This instance will be automatically created the first time a CurrentUser is needed in that session, and automatically destroyed when the session ends.


Genau so ein Verhalten will ich =), nur halt mit RMI

Meinst du ich muss einen eigene Scope Annotation machen und dazu einen eigenen Context siehe 5.1?


----------



## FArt (9. Mai 2011)

SirWayne hat gesagt.:


> Genau so ein Verhalten will ich =), nur halt mit RMI


Nicht für RMI. Für Beancalls, egal mit welchem Protokoll.



SirWayne hat gesagt.:


> Meinst du ich muss einen eigene Scope Annotation machen und dazu einen eigenen Context siehe 5.1?



So habe ich das verstanden. Dürfte nicht allzu schwer sein, denn so einen ähnlichen Context gibt es ja schon. Lediglich die Steuerung des Lebenszyklus müsste noch übernomen werden, denke ich.


----------



## Gast2 (9. Mai 2011)

FArt hat gesagt.:


> So habe ich das verstanden. Dürfte nicht allzu schwer sein, denn so einen ähnlichen Context gibt es ja schon. Lediglich die Steuerung des Lebenszyklus müsste noch übernomen werden, denke ich.



Hier habe ich nur etwas ausführlicheres gefunden Kapitel 6.
http://relation.to/service/File/12829
Werd ich mir mal anschauen, ob ich was finde. 
Bis jetzt fehlt mir noch das Verständniss wo ich mich einklinken kann und selber etwas Steuern kann. Welchen Context meinst du der ähnlich ist hab grad mal die Hierarchie von spi.Context angeschaut gibt ja einige. Such grad die sourcen mal dazu

EDIT: Sieht ganz interessant aus

```
/**
 * Abstract base class for representing contexts with thread local bean storage
 * 
 * @author Pete Muir
 */
public abstract class AbstractThreadLocalMapContext extends AbstractMapContext
```


----------



## Gast2 (9. Mai 2011)

Also ich versuche grad sowas hier:

```
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Inherited;
import java.lang.annotation.Target;

import javax.enterprise.context.NormalScope;

@Target(value = {TYPE, METHOD, FIELD })
@NormalScope
@Inherited
public @interface MyScope
{
}
```


```
import java.lang.annotation.Annotation;

import javax.enterprise.context.spi.Context;
import javax.enterprise.context.spi.Contextual;
import javax.enterprise.context.spi.CreationalContext;

public class MyContext extends AbstractThreadLocalMapContext-->Klasse gibts leider{

	/**
	 * Constructor
	 */
	public MyContext() {
		super(MyScope.class);
	}

	@Override
	public String toString() {
		String active = isActive() ? "Active " : "Inactive ";
		String beanStoreInfo = getBeanStore() == null ? "" : getBeanStore()
				.toString();
		return active + "session context " + beanStoreInfo;
	}

	@Override
	public void setActive(boolean active) {
		super.setActive(active);
	}

	@Override
	public void setBeanStore(BeanStore beanStore) {
		super.setBeanStore(beanStore);
	}

}
```


```
import javax.enterprise.inject.spi.Extension;

public class MyExtension implements Extension{

}
```

Ist das der richtige Weg? Warum habe ivh die ganzen org.jboss.weld.context Klasse nicht?
Was kommt den jetzt genau in die Extension rein?


----------



## Gast2 (10. Mai 2011)

Also ich hab jetzt zwar was selber gebasteltetes hinbekommen mit einem Interceptor, aber ich finds ehrlich gesagt nicht sehr toll...
Außerdem muss ich bei jedem Call die SessionID als Parameter mitgeben, um das Mapping hinzubekommen auch häßlich.

Jemand noch eine bessere Idee?


----------



## FArt (10. Mai 2011)

SirWayne hat gesagt.:


> Also ich hab jetzt zwar was selber gebasteltetes hinbekommen mit einem Interceptor, aber ich finds ehrlich gesagt nicht sehr toll...
> Außerdem muss ich bei jedem Call die SessionID als Parameter mitgeben, um das Mapping hinzubekommen auch häßlich.
> 
> Jemand noch eine bessere Idee?



Das Prinzip ist genau so richtig ok. Woher soll der Server denn sonst den Zusammenhang zur Session, die ja vom Client gepflegt wird, kennen und mit dem Call in Verbindung bringen. Läuft doch in HTTP auch so, nur dass du es nicht mitbekommst (url rewriting oder cookies).
Du kannst aber die Schnittstelle von diesen Metainformationen frei halten, wie es z.B. auch JAAS macht: 
Der Client pflegt die ID und deren Lifycycle. Bei jedem Call wird die ID über eine clientseitigen Interceptor an den Call angehängt. Auf dem Server wird die ID mit dem serverseitigen Interceptor ausgewertet und mit dem laufenden (Call Thread) verknüpft.


----------



## Gast2 (10. Mai 2011)

FArt hat gesagt.:


> Das Prinzip ist genau so richtig ok. Woher soll der Server denn sonst den Zusammenhang zur Session, die ja vom Client gepflegt wird, kennen und mit dem Call in Verbindung bringen. Läuft doch in HTTP auch so, nur dass du es nicht mitbekommst (url rewriting oder cookies).
> Du kannst aber die Schnittstelle von diesen Metainformationen frei halten, wie es z.B. auch JAAS macht:
> Der Client pflegt die ID und deren Lifycycle. Bei jedem Call wird die ID über eine clientseitigen Interceptor an den Call angehängt. Auf dem Server wird die ID mit dem serverseitigen Interceptor ausgewertet und mit dem laufenden (Call Thread) verknüpft.



Ok undeutlich ausgedrückt ich finds doof dass der Programmierer selber die ID mitgeben muss, die Info sollte automatisch übergeben werden.
Ja so einen clientseitigen Interceptor such ich noch. Wo muss ich den genau einhängen?

Zur ID Generierung passiert die auf dem Client oder Server? Ich dachte auf dem Server und der Client holt sich einmailig diese ID und hält diese.

Ja ich hab jetzt den ganzen ThreadLocal usw. selbst gemacht, da ich die weld Klassen nicht benutzen kann. Ich fand auch den Context nicht den du gemeint hast.

Außerdem weiß ich immer noch nicht so recht wie den akutellen User in meinen Context bekomme.


----------



## FArt (10. Mai 2011)

Ich habe mir Weld noch nicht näher angesehen, würde aber davon ausgehen, dass vieles deiner Arbeit dort schon als API zur Verfügung steht.


----------



## Gast2 (10. Mai 2011)

FArt hat gesagt.:


> Ich habe mir Weld noch nicht näher angesehen, würde aber davon ausgehen, dass vieles deiner Arbeit dort schon als API zur Verfügung steht.



Achso okay dachte du kennst es näher.

Ja aber wie gesagt stehen die Contexte mir gar nicht zu Verfügung.

Weißt du wo oder wie ich den Interceptor auf der clientseite einhänge?

grad sieht der Remote aufruf ja so aus: lookup und dann aufruf.


```
public Set<Angebot> getAngebote()  {
		return angebotRemoteService.getAngebote(sessionId);
	}
```


----------



## FArt (10. Mai 2011)

Das letzte mal habe ich das im JBoss 5 gemacht, ich glaube das ging so:. man konnte den Client-Interceptor-Stack mit der Annotation @RemoteBinding und dem Attribut interceptorStack konfigurieren.
Die Konfiguration definiert über AOP den Interceptorstack. Man kann seinen eigenen Stack von einem vorhandenen ableiten und dann den eigenen Interceptor dazu hängen. Die eigene Konfiguration kann man zu den anderen im JBoss dazu legen, aber man kann sie auch mit der Applikation deployen.


----------



## Gast2 (10. Mai 2011)

FArt hat gesagt.:


> Das letzte mal habe ich das im JBoss 5 gemacht, ich glaube das ging so:. man konnte den Client-Interceptor-Stack mit der Annotation @RemoteBinding und dem Attribut interceptorStack konfigurieren.
> Die Konfiguration definiert über AOP den Interceptorstack. Man kann seinen eigenen Stack von einem vorhandenen ableiten und dann den eigenen Interceptor dazu hängen. Die eigene Konfiguration kann man zu den anderen im JBoss dazu legen, aber man kann sie auch mit der Applikation deployen.



Ja ich hab grad sowas ähnliches gelesen aber das kapier ich grad nicht so ganz^^...

Da liegt der Interceptor doch auf dem Server oder? Wie komme ich dann an die Client-Infos dran? Irgendwo habe ich ein Denkfehler im Ablauf.

EDIT: Kann ich wirklich die SessionID mitgeben?

zurzeit sieht mein Remote Interface so aus

```
... getAngebote(String sessionID)
```

und nachher kann ich die Session ID weglassen werden und die komplette Signatur des Interfaces ändern??

```
getAngebote()
```

Ich kapiere nicht wie der Interceptor nun die ID an den Server geben soll? Der brauch irgendein Context sowie den HttpSessionContext oder sowas?


----------



## FArt (10. Mai 2011)

Ja. Das Interface muss dieses Informationen nicht liefern. Sonst müsstest du ja auch immer den Principal mitliefern.

Du bekommst im Interceptor ein Invocation Objekt mit den Metadaten des Calls. Die kannst du dann einfach anreichern und später wieder auslesen.

Die Konfiguration des Interceptors ist auf der serverseite. Realisiert wird der Interceptor Stack aber über den Bean Stub auf der clientseite.


----------



## Gast2 (10. Mai 2011)

FArt hat gesagt.:


> Ja. Das Interface muss dieses Informationen nicht liefern. Sonst müsstest du ja auch immer den Principal mitliefern.
> 
> Du bekommst im Interceptor ein Invocation Objekt mit den Metadaten des Calls. Die kannst du dann einfach anreichern und später wieder auslesen.


Ok das klingt gut. 



FArt hat gesagt.:


> Die Konfiguration des Interceptors ist auf der serverseite. Realisiert wird der Interceptor Stack aber über den Bean Stub auf der clientseite.



Wenn du dein Beispiel noch hast, kannst es ja mal bereitstellen wenn nicht all zu geheim ist  ...
Ich such mal im Netz nach einem Beispiel.

Hier mal was ich bis jetzt versucht habe:

```
@Interceptor
public class ClientSessionInterceptor implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
     private Object sessionId = "test";
     
     
     @AroundInvoke
     public Object injectSessionId(Invocation invocation) throws Throwable {
          invocation.getMetaData().addMetaData("sessionId", "sessionId", sessionId);
          return invocation.invokeNext();
     }
 
}
```


```
@Interceptor
public class SessionContextInterceptor implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 6606220960433411332L;

    @AroundInvoke
    public Object injectMap(InvocationContext ic, Invocation invocation) throws Exception {
        String sessionId = invocation.getMetaData("sessionId", "sessionId").toString();
        Map<String, Object> sessionContextMap = SessionRegistry.getSessionContextMap(sessionId);

    }

}
```


```
@Stateful
@Interceptors(SessionContextInterceptor .class)
@RemoteBinding(interceptorStack="ClientSessionInterceptor")
public class AngebotRemoteServiceImpl implements AngebotRemoteService {
```


Bekomm ich aber die Fehlermeldung

```
15:04:45,840 ERROR 
[org.jboss.kernel.plugins.dependency.AbstractKernelController] Error installing to Start: 
name=vfs:///D:/JBoss/jboss-6.0.0.Final/server/default/deploy/xPP_Prototyp.war_WeldBootstrapBean state=Create: org.jboss.weld.exceptions.DeploymentException: WELD-000069 An interceptor must 
have at least one binding, but client.ClientSessionInterceptor has none
```


----------



## Gast2 (10. Mai 2011)

Ah das AOP fehlt noch:


FArt hat gesagt.:


> Die Konfiguration definiert über AOP den Interceptorstack. Man kann seinen eigenen Stack von einem vorhandenen ableiten und dann den eigenen Interceptor dazu hängen.


Mhm ???:L




FArt hat gesagt.:


> aber man kann sie auch mit der Applikation deployen.



Im META-INF Ordner jboss-aop.xml anlegen oder?


----------



## FArt (10. Mai 2011)

Wenn ich mich recht erinnere, eine Archiv mit der Endung aop und einem passenden Deskriptor im META-INF.


----------



## Gast2 (10. Mai 2011)

FArt hat gesagt.:


> Wenn ich mich recht erinnere, eine Archiv mit der Endung aop und einem passenden Deskriptor im META-INF.



Klappt des überhaupt so wie ich das mache mit Annotations, weil ich find nur Beispiele wo implements gemacht wird.

Und im ServerInterceptor gebe ich 2 Argumente mit geht sowas überhaupt?


----------



## Gast2 (10. Mai 2011)

Mal eine andere Idee. Wenn ich ein eigenes LoginModul oder mich in einer einhänge und dort dann im Principal eine UUID erstelle. Oder im SessionContext die reinspeichere oder so etwas??

EDIT: Sie UUID sollte meines Wissens nach auf dem Server erstellt werden. Wenn der Client sich einen InitalContext holt sich eine UUID zurück liefern lässt diese in die Props reinschreibst und dann mit JAAS anmeldet. Diese kann man dann doch immer auslesen. Aber wie kann man in der contextData reinschreiben?


```
@Resource
    private SessionContext sessionContext;

    @AroundInvoke
    public Object injectMap(InvocationContext ic) throws Exception {
    	System.out.println(sessionContext.getCallerPrincipal());
    	System.out.println(sessionContext.getContextData());
```


----------



## FArt (11. Mai 2011)

Blätter mal ein paar Seiten zurück. Da hatte ich schon erwähnt, dass man die Prinzipalinformationen mit  einer Sessioninformationen anreichern könnte ;-)
Wo die SessionID erzeugt wird, sollte egal sein. Ich würde sagen das ist Geschmackssache.


----------



## Gast2 (11. Mai 2011)

FArt hat gesagt.:


> Blätter mal ein paar Seiten zurück. Da hatte ich schon erwähnt, dass man die Prinzipalinformationen mit  einer Sessioninformationen anreichern könnte ;-)
> Wo die SessionID erzeugt wird, sollte egal sein. Ich würde sagen das ist Geschmackssache.



haha okay =), aber die Frage ist wie ist es m besten/schönsten .

Ich dachte mal ein eigenes LoginModul, aber das wird nie aufgerufen =(
Bsp:

[XML]
    <application-policy name = "test">
          <authentication>
               <login-module 
                    code="login.TestLogin"
                    flag = "required">
                    <module-option
                         name="usersProperties">
                         props/prototyp-users.properties
                    </module-option>
                    <module-option
                         name="rolesProperties">
                         props/prototyp-roles.properties
                    </module-option>
                    <module-option name="principalClass">login.MyPrincipal</module-option>
               </login-module>
          </authentication>
     </application-policy>
[/XML]



```
public class TestLogin extends UsersRolesLoginModule{

	@Override
	protected Principal getIdentity() {
		System.out.println(super.getIdentity());
		return super.getIdentity();
	}
	@Override
	protected Principal createIdentity(String name) throws Exception {
		System.out.println("createIdentity");
		return new MyPrincipal(UUID.randomUUID().toString(), name);
	}	
}
```
Oder gibt es eine besser Möglichkeit?Und ich überseh gerade deinen Post?


```
@Resource
    private SessionContext sessionContext;

    @AroundInvoke
    public Object injectMap(InvocationContext ic) throws Exception {
    	System.out.println(sessionContext.getCallerPrincipal()); ist immer SimplePrinicpal WARUM=??
```

EDIT:
ähm lol?
Custom Principal class problem. SessionContext always return | PicketBox | JBoss Community

Anscheinend gefixed aber
https://issues.jboss.org/browse/JBAS-8427

EDIT EDIT: Meine 2te Idee wäre gewesen Die einvirmoment vond em InitalContext auszulesen aber ich finde keine passende Methode daüfr wie ich da hinkomm.
D.h auf ClientSeite einfach eine Prop setzen die auswerten, aber wie komme ich da hin?


----------



## Gast2 (11. Mai 2011)

Sorry aber ich versteh nicht wie Sachen an das Principal oder an den EJBContext hängen kann 

auf der clientseite mit prop.put("test","test"); gehts nicht, wird zumindest hier gesagt

Wie kann ich Clientinformationen an SessionBean weitergeben [Archiv] - Entwickler-Forum

aber wie hast du es dann gemeint?


EDIT: Spricht was dagegen 
	
	
	
	





```
SecurityContextAssociation.getSecurityContext().getUtil().getCredential()
```
zu nehmen?


----------



## TheDarkRose (11. Mai 2011)

SirWayne hat gesagt.:


> EDIT: Spricht was dagegen
> 
> 
> 
> ...



Eigentlich nicht, ist halt nur JBoss spezifisch. Theorpraktisch könntest dir auch eine eigene InitialContextFactory schreiben, wenn sichs was bringt.


----------



## Gast2 (11. Mai 2011)

Ja ein eigenes Principal wäre optimal gewesen aber irgendwie bekomme ich das ja nicht zum laufen siehe oben.

Vielleicht kann mir fart noch genauer sagen wie er die Principal mit infos anreichern würde


----------



## FArt (11. Mai 2011)

SirWayne hat gesagt.:


> Ja ein eigenes Principal wäre optimal gewesen aber irgendwie bekomme ich das ja nicht zum laufen siehe oben.
> 
> Vielleicht kann mir fart noch genauer sagen wie er die Principal mit infos anreichern würde



Ist schon etwas länger her und ich versuche mich zu erinnern: ich glaube wir hatten ein eigenes LoginModul und eine eine eigenen Prinicipal-Implementierung. Befüllen und auslesen passierte in den jeweiligen Interceptoren (Client und Server). Die eigentlichen Credentials wurden dann vom Loginmodul ausgewertet. 
Wichtig dabei war nur, dass der eigenen Interceptor nach dem SecurityInterceptor des JBoss drankommt, sonst sind die Objekte noch nicht initialisiert ;-)


----------



## Gast2 (11. Mai 2011)

FArt hat gesagt.:


> Ist schon etwas länger her und ich versuche mich zu erinnern: ich glaube wir hatten ein eigenes LoginModul und eine eine eigenen Prinicipal-Implementierung. Befüllen und auslesen passierte in den jeweiligen Interceptoren (Client und Server). Die eigentlichen Credentials wurden dann vom Loginmodul ausgewertet.
> Wichtig dabei war nur, dass der eigenen Interceptor nach dem SecurityInterceptor des JBoss drankommt, sonst sind die Objekte noch nicht initialisiert ;-)



Kanns so kompliziert brauch ich es gar nicht =). Es würde schon reichen wenn die eigene Prinicipal-Implementierung mit LoginModul funktioniert dann wäre alles gelöst ...Aber wie oben klappes es einfach nicht =(


----------



## Gast2 (12. Mai 2011)

Man muss tatsächlich ein SimplePrincipal Echo einführen damit es tut. Sieht auch nach workaround aus ...


```
@Override
	protected Group[] getRoleSets() throws LoginException {
		SimpleGroup rolesGroup = new SimpleGroup("Roles");
		rolesGroup.addMember(new SimplePrincipal("Echo"));
		Group callerPrincipal = new SimpleGroup("CallerPrincipal");
		callerPrincipal.addMember(this.getIdentity());
		Group[] newgroups = { rolesGroup, callerPrincipal };
		return newgroups;
	}
```

Danke alle nochmal für die Hilfe =)


----------



## FArt (12. Mai 2011)

SirWayne hat gesagt.:


> Sieht auch nach workaround aus ...



Ja, über den Principal ist es vermutlich ... ein Workaround, wenn auch m.E. vertretbar. 
Einfach gut dokumentieren


----------



## Gast2 (12. Mai 2011)

FArt hat gesagt.:


> Ja, über den Principal ist es vermutlich ... ein Workaround, wenn auch m.E. vertretbar.
> Einfach gut dokumentieren



Ich mein eher, dass man für einen eigenen Principal einen SimpelPrincipal("Echo") benötigt sonst erkennt JBoss den eigenen nicht. Das sieht schon nach hack aus ...


----------



## Gast2 (12. Mai 2011)

Okay ein Problem hab ich noch. 

Und zwar wenn ich beim JAAS anmelde und 2 Clients aufmache und 2 mal den gleichen Username eingebe wird der Login übersprungen d.h. ich komme nicht in mein TestLogin wo die sessionID vergeben wird. Gibt es da eine Möglichkeit das anders zu machen?

Und wenn ich auf dem Client ein Context.SECURITY_CREDENTIALS hinzufüge wird im Subject immer ein remove aufgerufen und der client bekommt beim nächsten call eine neue id...???:L


----------



## TheDarkRose (12. Mai 2011)

Wie meinst du das, der Login übersprungen? Könnte vielleicht daran liegen, das beide Clients in der gleichen VM liegen ?


----------



## Gast2 (12. Mai 2011)

TheDarkRose hat gesagt.:


> Wie meinst du das, der Login übersprungen?



Ja es wird in dem LoginModule kein login und initialize aufgerufen.

Nur wenn ich auf ClientSeite Context.SECURITY_CREDENTIALS setze dann wird der principal aber auch removed und bei jedem call neu angemeldet das will ich ja auch nicht 

siehe Subject methode remove zeile 1114



TheDarkRose hat gesagt.:


> Könnte vielleicht daran liegen, das beide Clients in der gleichen VM liegen ?


Puh ich starte in Eclipse 2 Swing Clients eigentlich laufen die dann nicht in der gleichen VM.


----------



## Gast2 (13. Mai 2011)

Hab grad nochmal nachgeschaut, laufen auf jeden Fall nicht in der gleichen VM!!!
Mhm gibt bestimmt irgendwo eine Einstellung oder Properties wie man das Verhalten abschalten kann.


----------



## Gast2 (13. Mai 2011)

Hallo ich hab die Stelle gefunden und zwar folgendes:
Im org.jboss.security.plugins.auth.JaasSecurityManagerBase gibt es einen chache und der schaut wieder nach dem SimplePrincipal!!!! ;( und findet natürlich dem Namen im cache und macht dann isValid true.

```
@param principal - the caller identity whose cached credentials are to
    be accessed.
    @param allowRefresh - a flag indicating if the cache access should flush
    any expired entries.
    */
   private DomainInfo getCacheInfo(Principal principal, boolean allowRefresh)
   {
      if( domainCache == null )
         return null;

      DomainInfo cacheInfo = null;
      synchronized( domainCache )
      {
          if( allowRefresh == true )
            cacheInfo = (DomainInfo) domainCache.get(principal);
          else
            cacheInfo = (DomainInfo) domainCache.peek(principal);
         if( cacheInfo != null )
            cacheInfo.acquire();
      }
      return cacheInfo;
   }

   private boolean validateCache(DomainInfo info, Object credential,
      Subject theSubject)
   {
           Object subjectCredential = info.credential;
      boolean isValid = false;
      // Check for a null credential as can be the case for an anonymous user
      if( credential == null || subjectCredential == null )
      {
         // Both credentials must be null
         isValid = (credential == null) && (subjectCredential == null);
      }

return isValid
}

   public boolean isValid(Principal principal, Object credential,
      Subject activeSubject)
   {
      // Check the cache first
      DomainInfo cacheInfo = getCacheInfo(principal, true); // hier
      if( trace )
         log.trace("Begin isValid, principal:"+principal+", cache info: "+cacheInfo);

      boolean isValid = false;
      if( cacheInfo != null )
      {
         isValid = validateCache(cacheInfo, credential, activeSubject);
         if( cacheInfo != null )
            cacheInfo.release();
      }
      if( isValid == false )
         isValid = authenticate(principal, credential, activeSubject);
      if( trace )
         log.trace("End isValid, "+isValid); 
      return isValid;
   }
```

Ich versuch jetzt mal den Cache abzuschalten.
CachingLoginCredentials | JBoss Community


----------



## Gast2 (17. Mai 2011)

Da jetzt eigentlich einigermaßen alles so tut wie ich wollte, versuche ich das gleiche nochmal über REST da kann ich dann wieder den SessionScoped verwenden schauen welche Variante angenehmer ist.


----------



## mvitz (17. Mai 2011)

Wobei REST eigentlich Stateless ist/sein sollte!


----------



## Gast2 (17. Mai 2011)

mvitz hat gesagt.:


> Wobei REST eigentlich Stateless ist/sein sollte!



Hast du eine Quelle? 
Also die Info so ein Szenario über REST zu machen, habe ich von einem JEE Architekt.


----------



## mvitz (17. Mai 2011)

Ich weiß es ist nur Wiki, aber hab gerade nicht mehr Zeit: Representational State Transfer ? Wikipedia


----------



## Gast2 (19. Mai 2011)

mvitz hat gesagt.:


> Ich weiß es ist nur Wiki, aber hab gerade nicht mehr Zeit: Representational State Transfer ? Wikipedia



Scheint wohl so zu sein:
Client:

```
public class RestClient {

	private static final String uri = "http://localhost:8080/project";
	
	public static void main(String[] args) {
		   // this initialization only needs to be done once per VM
        RegisterBuiltin.register(ResteasyProviderFactory.getInstance());
        Service1 service1 = ProxyFactory.create(Service1.class, uri);
        Service2 service2 = ProxyFactory.create(Service2.class, uri);
        service1.putParam("Hallo Welt");
        System.out.println(service2.getParam());
       
	}
	
}
```
Server:
Bean:

```
@SessionScoped
public class ParamBean implements Serializable{

	private static final long serialVersionUID = -3890162219225972547L;
	
	private String name;

	public void setName(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}
	
}
```

Service1

```
public class Service1Impl implements Service1{

	@Inject
	private ParamBean bean;
	
	@Override
	public void putParam(String param){
		bean.setParam(param);
	}

}
```

Service2

```
public class Service2Impl implements Service2{

	@Inject
	private ParamBean bean;
	
	@Override
	public String getParam(){
		return bean.getParam();
	}

}
```

Ist das ParamBean 2 mal eine unterschiedliche Instanz

EDIT: mal die 2 Projekte angehängt.


----------



## Gast2 (19. Mai 2011)

Aber das hier siehts interessant aus
A Single Line of Code Which Keeps Your REST/Hessian/HTTP Client State : Adam Bien's Weblog

EDIT: Nee schade klappt auch nicht mit 2 Service.

EDIT EDIT: Also mit JSF funktioniert sowas ein shared sessionScope Bean auf 2 Service. Also denk ich mal liegt die Magie im FacesServlet. Oder ?


----------



## Gast2 (19. Mai 2011)

Also nun gehts auch stateful mit sessionscope =)...

Das Problem war das die ProxyFactory jedes mal bei create einen neuen HttpClient aufmacht, wenn man einmal einen kriert und mitgibt klappt es auch


----------

