Remote-Sicht auf eine abstrakte Klasse?

BLR

Erfahrenes Mitglied
Hallo zusammen,

ich habe einen Client, der über das Remote-Interface (@Remote) eine Entitiy-DAO anspricht und dadurch die Entities anlegt, persistiert, und abfragt. Das klappt wunderbar.

Mein Vorgehen in Kürze:
1.@Remote-Interface mit Methoden definieren
2. Datenlayer diese Methoden implementieren lassen.
3. Datenlayer remote vom Client aus kontaktieren und diese Methoden auf der Seite vom Client aufrufen.
Funktioniert soweit....

Nun habe ich zwischen Punkt 1 und 2 eine abstrakte Klasse, die zum Teil Methoden ausführt, die jede DAO-Klasse ausführt. (Sinn und Zweck von der abstrakten Klasse)

Ich frrage mich ob es OOP-mäßig sinnvoll ist, ab die abstrakte Klasse das Remote-Interface implementiert, wäre das nicht doppelt-gemoppelt?
Kann man vllt. die @Remote-Annatation direkt an der abstrakten Klasse verwenden und der Client spricht die die Methoden an, die in der abstrakten Klasse definiert sind.
Oder kann der Client direkt das Remote-Interface ansprechen?

Wie könnte man geschickt in dieser Situation vorgehen?
Danke
 

saftmeister

Nutze den Saft!
Hi,

eine abstrakte Klasse kann jedes beliebige Interface implementieren. Aus API-Sicht macht es aber keinen Sinn, da ja eigentlich deine DAO das Interface implementieren soll. Ein Remote-Client wird die Methoden aus der abstrakten Klasse verwenden, wenn die DAO die Methoden selbst nicht implementiert.

Und zu letzt: Ein Remote-Client verwendet das Interface, nie die konkrete Klasse (also in dem Fall das DAO). Der Remote-Client braucht auch gar nicht zu wissen, was die konkrete Klasse ist. Er fragt den Applikation-Server nach einer Instanz einer Bean, die das gewünschte Interface implementiert. Entweder der Applikation-Server kennt eine Bean, die das tut, oder wirft eine entsprechende Exception.

Wenn ich es implementieren müsste:

1. Interface
2. Abstrakte Klasse
3. Konkretes DAO, welches von der abstrakten Klasse erbt und das Interface implementiert, und zudem @Remote(Interface.class) annotiert, um dem Applikation-Server eine Bean für den Lookup mitzuteilen.

4. Remote-Client kennt nur das Interface und erledigt einen lookup() via InitialContext, bekommt die Referenz auf eine Instanz einer Bean zurück (Klasse egal), welche dieses Interface im globalen JNDI-Baum registriert hat.
 

BLR

Erfahrenes Mitglied
Genauso habe ich es auch gemacht :)
Wollte nur noch ne Bestätigung haben.

Jetzt versuche ich gegen diese Stellestelle über context.lookup die ejb zu erreichen, was mir nicht gelingen mag. Ich weiss nicht, wie ich meinen Jboss 6.4 konfigurieren soll:


Java:
@Before
  public void setUp() {

  try {
  final Hashtable<String, Comparable> jndiProperties
  = new Hashtable<String, Comparable>();
  jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
  jndiProperties.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");
  jndiProperties.put("jboss.naming.client.ejb.context", true);  
  jndiProperties.put(Context.SECURITY_PRINCIPAL, "mr");
  jndiProperties.put(Context.SECURITY_CREDENTIALS, "meinPW");

  context = new InitialContext(jndiProperties);


  } catch (NamingException ex) {
  Logger.getLogger(TestClient.class.getName()).log(Level.SEVERE, null, ex);
  }

  @Test
  public void getConntection() {
  try {
  IEntityDAO iEntityDAO = (IEntityDAO) context.lookup("java:module/ProjectEJB!.server.ejb.IEntityDAO");
  assertNotNull(iEntityDAO);
  } catch (NamingException ex) {
  Logger.getLogger(VisTestClient.class.getName()).log(Level.SEVERE, null, ex);
  }

  }

  }

Und beim context.lookup kriege ich folgende Exception:
javax.naming.CommunicationException: Failed to connect to any server. Servers tried: [http-remoting://localhost:8080 (No connection provider for URI scheme "http-remoting" is installed)]
at org.jboss.naming.remote.client.HaRemoteNamingStore.failOverSequence(HaRemoteNamingStore.java:243)
at org.jboss.naming.remote.client.HaRemoteNamingStore.namingStore(HaRemoteNamingStore.java:149)
at org.jboss.naming.remote.client.HaRemoteNamingStore.namingOperation(HaRemoteNamingStore.java:130)
at org.jboss.naming.remote.client.HaRemoteNamingStore.lookup(HaRemoteNamingStore.java:271)
at org.jboss.naming.remote.client.RemoteContext.lookupInternal(RemoteContext.java:104)
at org.jboss.naming.remote.client.RemoteContext.lookup(RemoteContext.java:93)
at org.jboss.naming.remote.client.RemoteContext.lookup(RemoteContext.java:146)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at VisTestClient.getConntection(VisTestClient.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:35)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:115)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:97)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
at com.sun.proxy.$Proxy0.invoke(Unknown Source)
at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150)
at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)

Wo ist das Problem???
 

saftmeister

Nutze den Saft!
Der Code, den du gepostet hast, ist ein externer Client (eigene JVM-Instanz) oder eine Bean im JBoss-Container? Wenn es ein externer Client ist, hast du geprüft, ob das jboss-remote-naming jar im Classpath ist? Und wenn es im Classpath ist, ist die Version die korrekte? Also http-remoting hat es nicht immer gegeben.
 

BLR

Erfahrenes Mitglied
Hallo Saftmeister :)
Es ist ein externer Client. Den Ejb-Container konnte ich nicht zum Laufen bekommen.
Also normaleweise habe ich die jboss-client.jar aus dem jboss/bin/client Ordner im Classpath angeben. In meinem Fall hab ich einen Maven-Projekt und hab es als Dependency angefügt:
(Netbeans als IDE ==> manually install artifact)
So habe ich das mit Eclipse auch gemacht, also die jboss-client.jar als externe Lib angegeben und es ging....
Wo könnte ich nach einem Fehler schauen?