EJB Pool and EJB defined in 2 EAR - java

I'm totaly newbie in EJB and i need to understand how "ejb pool" works and how it is shared between EARS.
We have an EAR (named "ear1") deployed on WebSphere 8.5. This EAR contains some Stateless EJB3 (test.Ejb1, test.Ejb2, test.Ejb3) used by business-logic for access DB (using a "SQL-DB-datasource1").
We need to build a new EAR (named "ear2") and deploy it in the same websphere, but referencing a new datasource ("SQL-DB-datasource2").
Questions:
1. the EJB pool is the same and shared between ears, right?
2. if (mistake) i use same packages and the same EJB's names in both EARs (test.Ejb1, test.Ejb2, test.Ejb3), am i risking "ejb conflicts" between the two EARS when i will reference these EJB into rest services?
3. Or each EAR has "its own context" in the EJB pool?
4. "ear2" can access EJBs defined in "ear1"?
5. depends on how i make the "EJB lookup"?
Thanks!

No, each EJB has its own pool.
No, each application is loaded by a distinct class loader (by default), which means there is no risk of conflict, only a risk of potential confusion for you.
Yes.
Yes if the EJBs have remote interfaces. Yes but with caveats if the EJBs have local interfaces; see the "Local client views" section of the EJB modules topic in the Knowledge Center.
Yes, you will need to use a lookup string. The EJB container will print a CNTR0167I message when an application is starting, which will give you the lookup string. I would recommend using the java:global lookup string with an EJB reference (#EJB annotation or <ejb-ref>/<ejb-local-ref> XML element).

Related

What is java:comp/env scope rules?

I understand that java:comp/env is the node in the JNDI tree where you can find properties for the current Java EE component (a webapp, or an EJB), and also I know that each EJB has its own component environment ,also there is java:global and java:app and a java:module depending on that I have some questions
when I use Context envContext = (Context)initContext.lookup("java:comp/env"); to get initContext what Context exactly I get (global,app,module,webApp or EJB Context)?
Is there is certain rules applied for searching different scopes?
Let's say I have web application with many EJBs,does this means that I have many Initial Contexts (one for webApp and one for each EJB) or all of these resources are somehow collected under one context java:comp/env?
Many Thanks.
when I use Context envContext = (Context)initContext.lookup("java:comp/env"); to get initContext what Context exactly I get (global,app,module,webApp or EJB Context)?
Quoting from TomEE documentation http://tomee.apache.org/lookup-of-other-ejbs-example.html
In a webapp, the java:comp/env namespace is shared by all servlets.
This is essentially equivalent to the java:module namespace in Java EE
6. Understand there is a conflict in definition here and that for EJBs, java:comp is scoped at the component (the EJB itself) not the
module as with webapps.
Is there is certain rules applied for searching different scopes?
Quoting from JavaEE 6 Tutorial http://docs.oracle.com/cd/E19798-01/821-1841/girgn/index.html
The java:global JNDI namespace is the portable way of finding remote
enterprise beans using JNDI lookups. The java:module namespace is used
to look up local enterprise beans within the same module. The
java:app namespace is used to look up local enterprise beans packaged
within the same application. That is, the enterprise bean is packaged
within an EAR file containing multiple Java EE modules.
Let's say I have web application with many EJBs,does this means that I have many Initial Contexts (one for webApp and one for each EJB) or all of these resources are somehow collected under one context java:comp/env?
Based on above links, you will have not have many contexts.
Regarding question 3 on the scope of java:comp/env in presence of EJBs.
Traditionally (before JEE 6) java:comp/env was module level for war modules and EJB level for EJBs in jar modules.
In that model, one has to define environment entries (via resource-ref and env-entry in ejb-jar.xml, or for resource-refs since JEE5 one could use #Resource at the class level) for every single EJB.
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>B1</ejb-name>
<ejb-class>p1.B1</ejb-class> <!-- ejb-class should be skipped if bean is already defined via annotation -->
<env-entry>
<env-entry-name>entry1</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>value1</env-entry-value
</env-entry>
</session>
</enterprise-beans>
</ejb-jar>
Since JEE 6, one can deploy EJBs as part of war module. Whether war module is deployed directly or is part or ear module, it has a single java:comp/env namespace shared between all servlets, EJBs and any other code within that module. One can define environment entries in web.xml:
<web-app>
<env-entry>
<env-entry-name>entry1</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>value1</env-entry-value
</env-entry>
</web-app>
In this war based model, one could still have ejb-jar.xml to configure other aspects of EJBs, but env-entry for a given bean in ejb-jar.xml would end up injecting the environment value for all other beans in the war.
So, I would always use war archives for everything (possibly packaged in ear).
When I use Context envContext = (Context)initContext.lookup("java:comp/env"); to get initContext what Context exactly I get (global,app,module,webApp or EJB Context)?
You get the one you asked for, the one you correctly described as 'the current Java EE component (a webapp, or an EJB)'.
Is there is certain rules applied for searching different scopes?
You search within the scope you specify. I don't know what else your question could mean.
Let's say I have web application with many EJBs, does this means that I have many Initial Contexts (one for webApp and one for each EJB) or all of these resources are somehow collected under one context java:comp/env?
The question doesn't make sense. You have as many InitialContexts as you create. They are objects. What they refer to depends on what you lookup within that InitialContext. If you keep looking up "the current Java EE component (a webapp, or an EJB)", you will keep getting exactly that. All 'these resources' are 'collected' under their own names respectively, within java:comp/env.
As far of my knowledge by default the scope will be Global

Possible JNDI lookups within EJB container

I'm going through the EJB 3.1 spec and am trying to grasp the different possible ways a JNDI call can be made.
You can do it using a SessionContext and an InitialContext (or a self-created context based on the Initial- or SessionContext).
Based on which you use the syntax differs, but I can't seem to find the logic behind it.
So my question is: when can I use what syntax to use JNDI calls within an EJB container environment?
The rest of this question just serves as illustration of my point.
For example, I believe this is always possible for a correctly injected sessioncontext or created initialcontext:
ctx.lookup(java:global[/<app-name>]/<module-name>/<bean-name>[!<fully-qualified-interface-name>])
ctx.lookup(java:comp/env ...)
// special ones like these
ctx.lookup("java:comp/UserTransaction");
ctx.lookup("java:comp/ORB");
Sometimes (only for session context?) this shorter version is possible:
ctx.lookup(<bean-name>);
What about in an embedded environment, can only global references be used?
I usually inject EJBs inside EJB container with #EJB annotation. So the JDNI look ups are done by the server at deploy time.
For example JBOSS deployment:
INFO [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-2) JNDI bindings for session bean named TestBean in deployment unit subdeployment "MyEJB.jar" of deployment "MyProject.ear" are as follows:
java:global/MyProject/MyEJB/TestBean!my.project.TestBean
java:app/MyEJB/TestEJB!my.project.TestBean
java:module/TestEJB!my.project.TestBean
java:global/MyProject/MyEJB/TestEJB
java:app/MyEJB/TestBean
java:module/TestBean
Some are per EJB specification some are application server dependent.
If you have to make look ups from context I think the best way is to use java:global.
You can also find some additional info at: http://glassfish.java.net/javaee5/ejb/EJB_FAQ.html#POJOLocalEJB
jndi is a bit like a file system. You can refer to things using a relative path based on where you are in the tree (where you "cd"-ed to).
The injected session context is by default "positioned" on java:comp, so there you reference things that are available in java:comp, without the need to provide the "full path".
Note that java:comp itself is relative to a single EJB bean, or because of historical reasons to the entire Web module.
I'm not 100% sure what you mean with embedded environment, but if the code from which you are doing the JNDI lookup is not part of any of the predefined scopes (like java:module, java:app, etc) only java:global can be portably used.

Making sense of JPA and EJB3 and WebServices

I'm just getting started with JPA, creating stateless session beans from the JPA entities, then accessing the beans through a web service. While I have a lot of experience developing database backed web services "the old way", I have some questions about what's going on behind the scenes with this new "annotation driven approach".
What I see is, NetBeans sort of directs you to build applications in this manner though their wizards.
Create an Enterprise Application with EJB and Web Application modules.
Create Entity classes. I created mine from an existing database.
Create session beans from the entity class.
Create Web services from the session bean.
It all looks pretty simple, but what's going on behind the scenes? Specifically:
I see that the web service (created with the #WebService annotation) references my stateless session bean (using the #EJB reference).
What happens here? Does it just grab an instance of the EJB from the application server's EJB pool?
Nevermind. I was thinking of an instance where there was more than 1 table - meaning more than 1 type of Entity class and more than 1 type of EJB. I was looking at the web service and just seeing the #EJB reference and didn't understand who it was getting the bean type from that annotation. Just below that however, it the reference to the local bean interface - so that's that.
If there is more than 1 type of EJB deployed to the server, how does it know which one to grab?
The EJB is defined via the #Stateless and #Local annotations. The bean implementation references an EnityManager via the #PersistenceContext annotation.
Where is the jndi lookup to the database done (maybe in the persistence.xml file)?
Do all of the EJBs share a common EntityManager (assuming the EntityManager is thread safe)? If not, I know that the EnityManager utilizes a second level cache to help reduce trips to the database, are these caches somehow kept in sync?
I know this is a lot of questions, but they're all sort of related and there seem to be a lot of complicated concepts for something that's so easy to build through the wizards. I want to make sure I understand what's all going on here.
Thanks in advance!
What happens here? Does it just grab an instance of the EJB from the application server's EJB pool?
A JAX-WS web component endpoint (as opposed to a JAX-WS EJB endpoint) follows the typical servlet threading model, which means that typically there is one instance that is executed concurrently for each client. JAX-WS implementations are free to leverage pools of bean instances to handle a request in a fashion similar to stateless session EJB components. (source: Developing Applications for the JavaTM EE Platform FJ-310).
In all cases, it is fine to inject/look-up stateless beans because the container guarantees that the beans will always be thread safe. In affect, the container automatically serializes clients calls but uses instance pooling to make sure you still get concurrency benefits.
If there is more than 1 EJB deployed to the server, how does it know which one to grab?
Hmm... I didn't get this one. Can you clarify what you mean exactly? Why would there be any ambiguity?
Where is the jndi lookup to the database done (maybe in the persistence.xml file)?
In a Java EE environment, you specify your data source in a <jta-data-source> element in each persistence unit of the persistence.xml file (which can contain several persistence units) and the data source will be obtained by the EntityManager (only when needed, i.e. only if a data access is really needed).
Do all of the EJBs share a common EntityManager?
No. The EntityManager is a non-thread-safe object that should be used once, for a single business process, a single unit of work, and then discarded. In a Java EE environment using EJB 3, the default pattern is "entitymanager-per-request". A request from the client is send to the EJB 3 persistence layer, a new EntityManager is opened, and all database operations are executed in this unit of work. Once the work has been completed (and the response for the client has been prepared), the persistence context is flushed and closed, as well as the entity manager object. (source: Chapter 4. Transactions and Concurrency).

Is it possible to invoke methods of a session bean directly after deployment?

I'm using GlassFish. This is what I want to do. I have different ejb modules which can be deployed independently from each other. But I want to have one central ejb module where all the deployed modules have to register. This is because not all modules have to be deployed.
I thought the best way is if each ejb module contains a session bean (or what ever) with a specific method which will be immediately called after the module was deployed. But I found no such functionality. The whole process should happen after deployment because then a client can ask a session bean of the central ejb module which modules are registered at the moment.
I already tried the lifecycle functionality but there I have to create an own jar file which has to be placed in the lib directory of the application server which isn't really what I want. Furthermore if I call the register method of the central ejb module an exception will be thrown that this action is not allowed.
Does anybody know how I can manage this? Thanks for any help.
Can't you accomplish this by attempting to look them up in JNDI? They won't be there if they are not deployed. This is a registration and lookup mechanism, it just binds resources to names, but you can assume that if the name is not found it isn't deployed.

OC4J 10.1.3.4 problem with deploying multiple 2.1 EJBs

I am having troubles migrating from OC4J 10.1.2.3 to 10.1.3.1.4. The problem is for applications that have multiple EJBs (all are 2.1, no EJB 3.0). Jdeveloper will take the default ejb-jar.xml (the one required for Jdeveloper to run it on its stand-alone OC4J instance) and package it into each EJB JAR module NO MATTER what. This results in the app server drilling into each EJB JAR module when deploying, and find the same ejb-jar.xml file N times (where N = number of EJB Modules). This results in duplicate EJB references and will break any JNDI lookups such as: "java:comp/env/ejb/EJBName". Thus deploying an app that has 3 EJBs, EJB1, EJB2 and EJB3 causes the app server to register 9 EJBs instead of 3. I need a best practices way, but in between the way 10.1.3.4 and JDeveloper are acting the situation is rather dire...
Side note: They will work if the web app's JNDI look-up code is refractored to just "ejb/EJBName". This is not desirable though.
You should check the Oracle documentation to see which is your case.
The Oracle® Containers for J2EE Enterprise JavaBeans Developer's Guide is a good start
According to the Oracle® Containers for J2EE Services Guide, chapter 2: Using JNDI
when you use the form "ejb/EJBName" you perform "local" lookup. If you want to use the full form you must check the "Enabling Global JNDI Lookups" section of the "Using JNDI" chapter.
The problem was multiple reference in our deployment profiles. We were create a deployment profile for EACH EJB. This meant that each EJB had it's own ejb-jar.xml (this file contained a description of all EJBS in the project). Therefore, every time JDeveloper created an EJB, it placed a descriptor of all EJBS in each EJB it generated, causing an NxN amount of references. Therefore Nx(N-1) extra references.
Now, the key point is that Oracle Application Server 10.1.2.3.0 and bellow did not care about these duplicate references. However as we can see, 10.1.3.1.4 is a much different version and this did break.
Our fix: to have only 1 EJB Deployment profile that contains all of the EJB classes and the POJO's that they use. Remember, before there was 1 EJB Profile for each EJB... All this did was allow for Jdeveloper (which is crap IMHO) to correctly generate a valid EAR. A combination of Jdeveloper and Oracle's Application Server's crap is what caused this.

Categories

Resources