As your general doubt about the process of this physical separation of the components of your architecture, I will try to cover as much as possible.
The form I show here is not the only one that exists, it's just one that I consider organized and adopted with JavaEE when a distributed architecture is used that looks like its need.
Well, considering that you use maven
and also your current structure, I imagine you have three projects:
- A project with package
ejb
where your local interfaces and things like DAO
s, etc. are. It will suffer little change
- A project with package
war
, with dependency on package ejb
;
- A project with package
ear
, with dependency of the other two and package ejb
) and being modules of your war
.
If this is not the scenario you are using, please correct me to consider a correction in the response.
That said, let's go a way to make this separation. I'll put the steps and show you how you can do this separation in your project.
1. Using local and remote interfaces
The first step is to analyze your current project in search of what will be made available by remote interfaces or not. There are several ways to do this, many people usually provide a single remote interface for all services. Particularly I do not like it, I think it's an unorganized form when you have a single remote interface, because you lose some of the semantics of the thing.
It's very likely that you'll need a legal refactoring in your project so you do not have duplicate things and more importantly, do not remotely expose what you do not need to expose.
2. Project Modules
For the project structure, I will consider that you have a project grouper, let's call it EAR
. This root-project
will have the following modules:
-
root-project
: this project will contain only remote interfaces, no implementation will be project4remote
and it has no dependency on other modules in your application.
An example of a remote interface is basically annotated with ejb
and you say how you want the result to be serialized, it would look like this:
import javax.ejb.Remote;
@Remote
public interface RemoteInterface { }
-
@Remote
: This is basically your project with package project4local
, changing only that it should implement the remote interfaces, package ejb
and obviously has dependency on ejb
.
I imagine you already have local interfaces, but if you do not have it, it's just something noted like project4remote
, something like this:
import javax.ejb.Local;
@Local
public interface LocalInterface { }
In the implementation of it can be the same implementation of the remote interface, something like this:
import javax.ejb.Stateless;
@Stateless(name = "yourServiceBean")
public class LocalRemoteImpl implements LocalInterface, RemoteInterface { }
-
@Local
: This web project of your projects will only depend on project4web
because you will need such interfaces to consume the services that are in the container . >
-
project4remote
: this is the project that will group what will be installed in the project4ear
container, so it will depend on the projects. An example configuration might be this:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.brunocesar</groupId>
<version>0.0.1-SNAPSHOT</version>
<artifactId>root-project</artifactId>
<packaging>pom</packaging>
<build>
<finalName>${project.artifactId}</finalName>
<defaultGoal>clean install</defaultGoal>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<modules>
<module>project4ear</module>
<module>project4local</module>
<module>project4remote</module>
<module>project4web</module>
</modules>
</project>
3. How do lookup of your remote interfaces?
As you apparently are not using anything that does this lookup for you, I will show you just how you can do it "at hand." In summary it's something like this:
final InputStream fis = SuaClasse.class.getResourceAsStream("/ejb-client.properties")
final Properties props = new Properties();
props.load(is);
final InitialContext ic = new InitialContext(props);
final SuaInterfaceRemota interface = (SuaInterfaceRemota) ic.lookup("nome:/doRecurso/PublicadoNaJNDI");
interface.seuMetodo(args);
I suggest you look at how the interfaces are being published, there are always several ways to access them through JNDI. I do not remember what it's like in JBoss's case, so take a look at the log so you can do the lookup correctly.
For client properties, see here and also the gifts < a href="http://docs.oracle.com/javase/7/docs/api/javax/naming/Context.html"> here , if you need any of the ones that were not put in the example. An example configuration would be this:
java.naming.factory.url.pkgs=org.jboss.ejb.client.naming
remote.connections=${remote.connections}
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
remote.connection.${remote.connections}.host=${remote.connection.host}
remote.connection.${remote.connections}.port=${remote.connection.port}
remote.connection.${remote.connections}.username=${remote.connection.username}
remote.connection.${remote.connections}.password=${remote.connection.password}
Where JEE
is the connection ID, such as remote.connections
.
Obs. . I have taken these parameters from a project I already have set up, if you do not use maven's property in your build, just change it.