2013-01-31 11 views
6

Questa è la mia prima domanda in Stack Overflow, quindi mi aspetto che non sia troppo semplice. Ho cercato su Internet una buona soluzione ma ormai non ce l'ho.Un modo semplice per accedere a un ejb remoto situato in un altro server

Sono un grande inizio per EJB, JNDI e Java EE in generale, ma negli ultimi mesi sono stato in grado di fare alcune cose accettabili in questo ambiente. Ora sto concentrando un problema sul lavoro e ormai la soluzione non è buona come vorrei.

Lo scenario è questo: ho un'applicazione EAR in esecuzione in Glassfih 3.1.2. Ho dichiarato EJB all'interno di questa app EAR con bean privi di stato che offrono metodi attraverso un'interfaccia remota.

Questo è il mio Bean remoto in esecuzione in un server denominato server1, ad esempio

package com.booreg; 

import javax.ejb.LocalBean; 
import javax.ejb.Stateless; 

import com.booreg.IMyRemoteBean; 

@Stateless 
@LocalBean 
public class MyRemoteBean implements IMyRemoteBean 
{ 
    @Override 
    public String helloWorld() 
    { 
     return "Hi what's up boy"; 
    } 
} 

Questa è l'interfaccia per esso

package com.booreg; 

import javax.ejb.Remote; 

@Remote 
public interface IMyRemoteBean 
{ 
    public String helloWorld(); 
} 

Poi ho una seconda applicazione EAR che deve eseguire imperativamente su un altro server, chiamato server2. La seconda APP utilizza JSF e Managed Beans. Abbiamo un bean gestito che agisce come un client remoto di MyRemoteBeanRemote, come questo:

package com.nucleus; 

import javax.ejb.EJB; 
import javax.faces.bean.ManagedBean; 
import javax.faces.bean.ViewScoped; 

import com.booreg.IMyRemoteBean; 

@ManagedBean 
@ViewScoped 
public class MyManagedBean 
{ 
    @EJB(name="TheRef") IMyRemoteBean myRemoteBean; 

    public String getPhrase() { return myRemoteBean.helloWorld(); } 
} 

Sono arrivato al punto che questo funziona dichiara un file/sun-web.xml ejb-ref all'interno WEB-INF in il mio progetto web.

<ejb-ref> 
    <ejb-ref-name>TheRef</ejb-ref-name> 
    <jndi-name>corbaname:iiop:server1:3700#java:global/booreg/booreg.ejb/MyRemoteBean!com.booreg.IMyRemoteBean</jndi-name> 
</ejb-ref> 

Capisco che con questo file sun-web.xml il jndi nome fa la seconda app per sapere dove trovare l'implementazione EJB situato in un primo momento app. Ma qui ho alcune domande:

  1. È necessario dichiarare una voce ejb-ref per ciascuna interfaccia EJB che ho nel mio progetto?
  2. Come evitare di creare un riferimento statico a server/porta (server1: 3700 durante lo sviluppo) all'interno di sun-web.xml? Quando questo andrà in produzione dovrò cambiare manualmente il nome del sever per ognuno ?? Questo suona bizzarro. Posso usare qualche tipo di variabile sul lato server per specificare server/porta?

Mi aspetto che mi sia spiegato abbastanza bene.

Molte grazie

Aggiornamento: finalmente, grazie a questo link vedo che è possibile fare riferimenti al server EJB (server1) creazione di un file jndi.properties all'interno del mio percorso di classe. Questo file dovrebbe contenere righe come questa.

java.naming.factory.initial=com.sun.enterprise.naming.SerialInitContextFactory 
java.naming.factory.url.pkgs=com.sun.enterprise.naming 
java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl 
org.omg.CORBA.ORBInitialHost=server1 
org.omg.CORBA.ORBInitialPort=3700 

Ma sto ancora affrontando problemi. Quando si distribuisce l'applicazione appare l'eccezione successiva su server1 e non posso distribuire l'applicazione.

ADVERTENCIA: IOP00100006: Class com.sun.jersey.server.impl.cdi.CDIExtension is not Serializable 
org.omg.CORBA.BAD_PARAM: ADVERTENCIA: IOP00100006: Class com.sun.jersey.server.impl.cdi.CDIExtension is not Serializable vmcid: SUN minor code: 6 completed: Maybe 
    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 com.sun.corba.ee.spi.orbutil.logex.corba.CorbaExtension.makeException(CorbaExtension.java:248) 
    at com.sun.corba.ee.spi.orbutil.logex.corba.CorbaExtension.makeException(CorbaExtension.java:95) 
    at com.sun.corba.ee.spi.orbutil.logex.WrapperGenerator.handleFullLogging(WrapperGenerator.java:387) 
    at com.sun.corba.ee.spi.orbutil.logex.WrapperGenerator.access$400(WrapperGenerator.java:107) 
    at com.sun.corba.ee.spi.orbutil.logex.WrapperGenerator$2.invoke(WrapperGenerator.java:511) 
    at com.sun.corba.ee.spi.orbutil.proxy.CompositeInvocationHandlerImpl.invoke(CompositeInvocationHandlerImpl.java:99) 
    at $Proxy117.notSerializable(Unknown Source) 
    at com.sun.corba.ee.impl.orbutil.ORBUtility.throwNotSerializableForCorba(ORBUtility.java:783) 
    at com.sun.corba.ee.impl.encoding.CDROutputStream_1_0.write_abstract_interface(CDROutputStream_1_0.java:697) 
    at com.sun.corba.ee.impl.encoding.CDROutputObject.write_abstract_interface(CDROutputObject.java:545) 
    at com.sun.corba.ee.impl.javax.rmi.CORBA.Util.writeAbstractObject(Util.java:493) 
    ... 

Qualcuno ha qualche idea?

+0

Se si cerca l'ejb remoto tramite jndi in codice, è possibile utilizzare le variabili jvm del server per porta e server. Forse è possibile accedere alle variabili jvm all'interno di sun-web.xml. Non so se è possibile. – djmj

+0

Mi piace mantenere il codice il più semplice e pulito possibile. Per questo motivo non mi piace utilizzare la ricerca all'interno del mio codice in cui @EJB semplifica il lavoro. – dgisbert

+0

Hai considerato di organizzare le due istanze in un cluster? – gcvt

risposta

0

@dgisbert

Nel l'ultimo commento che lei ha citato, che un server è un pubblico e un altro è il server interno della vostra azienda. Ben chiamare il livello Application da un server pubblico non è una buona pratica. Significa che stai dando direttamente accesso al tuo livello aziendale critico. Suggerirei piuttosto di avere un livello di servizio Web in cima alle chiamate EJB in modo che ogni chiamata proveniente dal sito pubblico debba passare attraverso WebServer -> App Server. In questo modo è possibile ridurre notevolmente il rischio di attacchi

+0

Grazie per la risposta, ma non vedo il motivo per cui è meglio avere un livello intermedio di servizio Web invece di avere chiamate EJB remote. Tramite chiamate EJB remote sto controllando quali parti della mia applicazione sono visibili in remoto attraverso l'interfaccia remota. – dgisbert

+1

@dgisbert - non riguarda i servizi che esponi - riguarda l'accesso diretto al tuo Business Layer aziendale a parti esterne. I suggerimenti architettonici tipici dovrebbero avere uno strato DMZ tra sistemi esterni e interni (ftp.software.ibm.com/ software/razionale/web/whitepapers/r_wp_securityrichwebapps.pdf) .. Ricerca Google/Bing per Securing_Enterprise_Web_Applications_at_the_Source. È un documento lungo, ma è necessario leggerlo in tempo. Un hacker (Genius guys?) Può sfruttare questa vulnerabilità e attaccare il tuo livello. Continuano a venire con nuovi approcci – user1428716

+0

Grazie ancora per i tuoi commenti. Non sono uno specialista della sicurezza, ma sono preoccupato per la sicurezza. Ho scaricato il documento che hai menzionato. È lungo, ma darò un'occhiata. Informazioni su DMZ, abbiamo già server1 in una DMZ. Quindi, possiamo controllare tutto il traffico tra server1 e server2 attraverso il nostro firewall. L'ho chiamato public perché permettiamo connessioni web su server1 (ovviamente le nostre pagine sono protette da password) e tra server1 e server2 permettiamo solo chiamate ejb remote. Pertanto, IMHO equivale ad avere un livello di servizio Web tra cui server1 e server2 che dispongono di livello di servizio EJB remoto. – dgisbert

Problemi correlati