Reputation: 547
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.
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.
Upvotes: 3
Views: 2546
Reputation: 923
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.
Upvotes: 0