JBoss6 Remoting

G

Gast2

Gast
Hallo zusammen,

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

Interface
Java:
@Remote
public interface AngebotRemoteService {

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

Client:
Java:
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
Java:
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
Code:
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

Top Contributor
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:
Java:
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);
 
G

Gast2

Gast
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

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

Gast2

Gast
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?
 
G

Gast2

Gast
Wenn ich den Service Aufrufe bekomme ich eine CNFE, benötige ich noch irgendwelche jars auf dem Client?
Java:
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)
 

mvitz

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

Gast2

Gast
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:
 
Zuletzt bearbeitet von einem Moderator:
G

Gast2

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

Jetzt hab ich so ein Gerüst
Java:
@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
Java:
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
Java:
@Stateful
@SessionScoped
public class UserRemoteBean{
	
	private String name;

Darf das Bean keinen SessionScoped haben? Versteh glaub das Problem gerade nicht ganz.
 
Zuletzt bearbeitet von einem Moderator:
G

Gast2

Gast
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:
Java:
@Remote
public interface LoginRemoteService {
	
	public void login(String name, char[] pwd);
}

Impl:
Java:
@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
Java:
@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:
Java:
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...
 
Zuletzt bearbeitet von einem Moderator:
G

Gelöschtes Mitglied 5909

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

Java:
    @Inject
    private UserRemoteBean user;

@EJB hin?

Java:
    @EJB
    private UserRemoteBean user;
 
G

Gast2

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

Java:
    @Inject
    private UserRemoteBean user;

@EJB hin?

Java:
    @EJB
    private UserRemoteBean user;

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
Java:
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
 
G

Gast2

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

Java:
    @Inject
    private UserRemoteBean user;

@EJB hin?

Java:
    @EJB
    private UserRemoteBean user;

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?
 
G

Gelöschtes Mitglied 5909

Gast
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 :)
 
G

Gast2

Gast
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.
 
G

Gast2

Gast
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
 
Zuletzt bearbeitet von einem Moderator:

FArt

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

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

Gast2

Gast
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.

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.

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?
 
G

Gast2

Gast
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?!?!

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?^^


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 =)
 
G

Gast2

Gast
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
 
Zuletzt bearbeitet von einem Moderator:

FArt

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

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
 
G

Gast2

Gast
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.


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.
 

Anhänge

  • Client.zip
    3,5 KB · Aufrufe: 2
  • server.zip
    10,7 KB · Aufrufe: 4
Zuletzt bearbeitet von einem Moderator:

FArt

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

Gast2

Gast
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

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

Gast2

Gast
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 .

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
 
Zuletzt bearbeitet von einem Moderator:
G

Gast2

Gast
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:...
Java:
MyService myService = context.lookup("myService");
MyService myService1 = context.lookup("myService");
 

FArt

Top Contributor
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:...
Java:
MyService myService = context.lookup("myService");
MyService myService1 = 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!!!!
 
G

Gast2

Gast
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
Code:
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.

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.
 
Zuletzt bearbeitet von einem Moderator:

FArt

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



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.

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.
 
G

Gast2

Gast
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.

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.
Wenn du nicht immer über 5 Ecken reden würdest und einfach sagen und zeigen würdest was Sache ist, wäre wohl einfacher zu verstehen was Sache ist. ;)

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.
Zeit hab ich wohl eher keine verschwendet, anscheinend eher du. Aber immer nur Sachen behaupten, ich weiß was falsch ist, ist doch glas klar usw. Aber dann nicht eine Lösung oder Beispiel zeigen können, kommt eben milde ausgedrückt komisch rüber.

Letzter Tipp: lasse deine Architektur mal von einem Software-Architekten reviewen, der Erfahrung mit Enterpriseumgebungen hat.

Klasse Aussage, meinst ich würde keinen in der Firma Fragen wenn es hier einen geben würde ;)



2 mal aufrufen des remote Serice mit log aufm Server
Code:
13:52:44,200 INFO  [STDOUT] Login remote.LoginRemoteServiceImpl@d718f3

13:52:44,200 INFO  [STDOUT] No-Interface view for endpoint [ jboss.j2ee:jar=xPP_Prototyp.war,name=UserRemoteBean,service=EJB3 ] and session a3b3o6g-5y1nl4-gn7bwyb1-1-gn7co4xo-et

13:52:44,231 INFO  [STDOUT] Login remote.LoginRemoteServiceImpl@d718f3

13:52:44,231 INFO  [STDOUT] No-Interface view for endpoint [ jboss.j2ee:jar=xPP_Prototyp.war,name=UserRemoteBean,service=EJB3 ] and session a3b3o6g-5y1nl4-gn7bwyb1-1-gn7co4xo-et
Dann neuer lookup
Code:
13:53:44,870 INFO  [STDOUT] Login remote.LoginRemoteServiceImpl@7a5cd7

13:53:44,870 INFO  [STDOUT] No-Interface view for endpoint [ jboss.j2ee:jar=xPP_Prototyp.war,name=UserRemoteBean,service=EJB3 ] and session a3b3o6g-5y1nl4-gn7bwyb1-1-gn7co53b-f4
Sorry für meinen minderen IQ, aber für mich ist das unlogisch ???:L
Für mich sollte der Stateful Bean sich den Zustand merken.

EDIT: Muss ich anstatt DI , JNDI verwenden ?
http://www.ralf-gitzel.info/JEE-07-SessionBeans.pdf
 
Zuletzt bearbeitet von einem Moderator:

FArt

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

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?
 
G

Gast2

Gast
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.

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.

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 =)


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 :)?
 
Zuletzt bearbeitet von einem Moderator:

FArt

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

Gast2

Gast
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.
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.

Ü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.

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 ;)

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

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

Gast2

Gast
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

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

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

TheDarkRose

Gesperrter Benutzer
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.
 
G

Gast2

Gast
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

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.
 
Zuletzt bearbeitet von einem Moderator:

TheDarkRose

Gesperrter Benutzer
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.
 
G

Gast2

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

Hab eine auth.conf in der META-INF angelegt
Code:
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
Java:
        SecurityClient client = SecurityClientFactory.getSecurityClient();
        client.setJAAS("clientlogin", new Client.MyCallbackHandler());
        client.login();

Java:
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

Gesperrter Benutzer
Hmm, SecurityClient verwende ich gar nicht. Nehm dazu den LoginContext
Java:
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)
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
G JBoss6 UnitTest Application Tier 21

Ähnliche Java Themen

Neue Themen


Oben