Frage

We have a couple of JBoss servers on different machines with different IPs (not a cluster, single standalone JBoss 7.1.1 instances that belong to different customers). The exact same EAR is deployed on all systems. We try to send a POJO called Group from one system to another system.

The problem

We tried everything but are unable to get the remote methods called. The connection is established but not used (the local bean was used in some cases). What can we do to get the communication to work?

We have tried to follow these manuals (without any luck so far):

EJB invocations from a remote server instance

This manual states:

Note that this chapter deals with the case where the bean is deployed on the "Destination Server" but not on the "Client Server".

The bean is deployed on both servers because there is no destination or client server. Both servers can be client or destination, depending on the scenario, e.g. customer A could want to send a Group to customer B today and customer C could want to send a Group to customer A tomorrow. The day after tomorrow, customer A might want to send a Group to customer C.

Source: https://docs.jboss.org/author/display/AS71/EJB+invocations+from+a+remote+server+instance

EJB invocations from a remote client using JNDI

This didn't worked either. This manual uses .properties-files that cannot be changed at runtime which makes this approach unusable, even if it would have worked (which it didn't).

Source: https://docs.jboss.org/author/display/AS71/EJB+invocations+from+a+remote+client+using+JNDI

Remote EJB invocations via JNDI - EJB client API or remote-naming project

This approach sets "jboss.naming.client.ejb.context" to true. This causes a SecurityException because EJBClientContext.setSelector is called.

Source: https://docs.jboss.org/author/display/AS71/Remote+EJB+invocations+via+JNDI+-+EJB+client+API+or+remote-naming+project

Project structure

This is our project structure:

project/
    ear/
        pom.xml
    war/
        pom.xml
        src/main/java/com/acme/ejb/
            DefaultGroupImportBean.java
    ejb/
        pom.xml
        src/main/java/com/acme/ejb/
            DefaultGroupTransferBean.java
    ejb-api/
        pom.xml
        src/main/java/com/acme/ejb
            GroupImportBean.java
            GroupTransferBean.java
            RemoteEjbClient.java

This is the class that does the lookup:

public class RemoteEjbClient {

    private static final String INITIAL_CONTEXT_FACTORY = "org.jboss.naming.remote.client.InitialContextFactory";

    public GroupTransferBean lookupGroupTransferBean(NamingContextConfiguration namingContextConfiguration)
        throws NamingException {

        Context context = createInitialContext(namingContextConfiguration);
        return (GroupTransferBean) context.lookup(namingContextConfiguration.getLookupName());
    }

    private Context createInitialContext(NamingContextConfiguration namingContextConfiguration) throws NamingException {
        Properties jndiProperties = new Properties();
        jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
        jndiProperties.put(Context.PROVIDER_URL, namingContextConfiguration.getProviderUrl());
        jndiProperties.put(Context.SECURITY_PRINCIPAL, namingContextConfiguration.getPrincipal());
        jndiProperties.put(Context.SECURITY_CREDENTIALS, namingContextConfiguration.getCredentials());

        return new InitialContext(jndiProperties);
    }
}

NamingContextConfiguration is a POJO that describes another system. We store -_NamingContextConfiguration_s in our database (they must be configurable at runtime!). The principal has been added with add-user.sh (Application User).

GroupTransferBean.java:

public interface GroupTransferBean {

    void pushGroup(Group group);

    void pushResources(String url, List<String> resources);
}

GroupImportBean.java:

public interface GroupImportBean {

    public void importGroup(Group group);

    public void importResources(String url, List<String> resources);
}

DefaultGroupTransferBean.java:

@Stateless(mappedName = "GroupTransferBean")
@Remote(GroupTransferBean.class)
public class DefaultGroupTransferBean implements GroupTransferBean {

    @EJB
    private GroupImportBean groupImportBean;

    @Override
    public void pushGroup(Group group) {
        groupImportBean.importGroup(group);
    }

    @Override
    public void pushResources(String url, List<String> resources) {
        groupImportBean.importResources(url, resources);
    }
}

DefaultGroupImportBean.java:

@Stateless
@Remote(GroupImportBean.class)
@Interceptors(SpringBeanAutowiringInterceptor.class)
public class DefaultGroupImportBean implements GroupImportBean {

    @Autowired
    private GroupRepository groupRepository;

    @Override
    public void importGroup(Group group) {
        groupRepository.save(group);
    }

    @Override
    public void importResources(String url, List<String> resources) {
        // Do some magic
    }
}

The RemoteEjbClient is called by a Spring controller.

War es hilfreich?

Lösung

Nearly the same question as described here: Lookup of same EJB on multiple servers

It seems to be impossible to get a reliant connection between multiple servers via EJB, so we ended up using JMS for our server to server communication. Maybe thats an option for you, too.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top