Division of the EJB Project

Asked

Viewed 694 times

6

I have an EJB project, to implement the system the project needs to be divided into 3.

  • The Database on a machine
  • The User Interface on another host
  • And the EJB(Services) in another

But the whole system is developed in ejb, the EAR package is in the following form.

  • EAR
    • EJB
    • WAR

As far as I understand I should leave the WAR package on one of the hosts, and the EJB running on another, but how do I break the project this way? We are using JBOSS EAP 6.3 on both servers, the database separation part is already done.

  • The package WAR and the package EJB will always be deployed separately? Are you using any tool to build/packaged?

  • @Brunocésar 1- Projects from this will be deployed following this architecture. 2- We use Maven.

  • Are you sure you want to do this separation? It is no longer recommended as there is a very impactful overhead in the system. What benefits do you expect from this? I prefer to keep only the conceptual separation of these layers, physically separating at most in Packages and not using remote interfaces. See: Prefer local interface.

  • @Caffé It was not a decision made by us but by the infra team, security and our manager, and mere mortals pay, so it will have to be =(but I never dealt with it. But the goal of the backend is to leave the web layer on a Web server of life and the service layer in the datacenter.

  • I don’t know if separation is a very good idea, but it seems to be a very interesting experience.

  • @Caffé is actually discouraged (and even bad practice) the use of remote interfaces when you can use the places, that is, when we are in the same container (even why serialize the answer in this case?). However it is quite common to have this physical separation (for example when one wants to have control in scaling only certain parts, specific caching, etc.) and in this case we use remote interfaces. Of course it is difficult to say that the decision is right or wrong, even because.

  • @João I still have doubts to help you: is your doubt specific about the separation of the packages? How will you do it lookup of the remote interfaces? If so lookup, intends to do "in hand" or will use something like spring in your package WAR? Is it about packaging/deploy forms? Or even about separating interfaces on-premises/remotely? Finally: depending on the doubt it is necessary to know, is using EJB 3+?

  • @Brunocésar In fact it is a doubt of everything, I never did this procedure anywhere, in reality only that of the databases that we already worked like this, which are managed by the container, now the separation of the packages, lookup etc have never done and found no material of this content. We are using Apache Wicket, we do not use spring but if necessary... and we use Ejb 3 + JPA + Ibernate

  • @Brunocésar when I spoke on remote interfaces I was obviously talking about separating the layers in different containers, because that is precisely what remote interfaces are for. It’s not so hard to say what’s right or wrong: distributing system layers in different containers rarely (nowadays who knows ever) will be the best solution, whether for scheduling, or for security.

  • @Caffé if you say, then

Show 5 more comments

1 answer

3


As your doubt is general regarding 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 similar to its need is used.

Well, considering he does maven and also its current structure, I imagine it has three projects:

  • a project with package ejb where your local interfaces and other things like DAOs, etc. It will undergo little change
  • a project with package war, dependent on the package ejb;
  • a project with package ear, dependent on the other two (package ejb and package war) and being modules of your EAR.

If this is not the scenario you are using, correct me to consider a correction in the response.

That being said, let’s go to a way to make this separation. I will put the steps and show how you can make this separation in your project.

1. Use of local and remote interfaces

The first step to be done 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 not like, I find a way not organized when you have a single remote interface, even because it loses a little the semantics of the thing.

It is very likely that you will need a Refactoring legal in your project so as not to have duplicated things and more importantly, do not remotely expose what you do not need to expose.

2. Modules of Projects

For the structure of the project, I will consider that you have a project grouper, let’s call it root-project. This root-project will have the following modules:

  • project4remote: this project will contain only remote interfaces, no implementation package will be ejb and it has no dependency on other modules of its application.

An example of remote interface is basically annotated with @Remote and you say how you want the result to be serialized, it would be like this:

import javax.ejb.Remote;

@Remote
public interface RemoteInterface { }
  • project4local: This basically your project with package ejb, changing only that it should implement the remote interfaces, the package continues as ejb and obviously has a dependency on project4remote.

I imagine you already have local interfaces, but if not, it’s just something noted as @Local, something like that:

import javax.ejb.Local;

@Local
public interface LocalInterface { }

In its implementation it can be the same implementation of the remote interface, that is, something like this:

import javax.ejb.Stateless;

@Stateless(name = "yourServiceBean")
public class LocalRemoteImpl implements LocalInterface, RemoteInterface { }
  • project4web: of its projects will depend only on the project4remote because it will need such interfaces to consume the services that are in the container.
  • project4ear: this is the project that will group what will be installed in the container JEE, then it will be dependent on the projects. An example configuration could 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 to do lookup of its remote interfaces?

How you apparently aren’t wearing anything that does this lookup for you, I’ll show you just how you can do it "at hand". In short 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 to observe how the interfaces are being published, there are always several ways to access them by JNDI. I don’t remember what it’s like in the case of Jboss, so take a look at the log so you can do the lookup correctly.

For customer properties, see here and also the gifts here, if you need any of the ones that were not placed 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}

In which remote.connections is the identification of the connection, for example, default.

Obs.. I took these parameters of a project that I have already configured, if not use Property Replacement Maven in your build, just change.

  • Thank you very much, the architect of systems came back, and solved problem by hitting mouth with the infra, we will change the deployment, but I will use your answer for study, until I liked the challenge and never know when I will need, since I never worked with remote interfaces.

  • @Cool John, any doubt just talk :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.