Why LocalEntityManagerFactoryBean class is called "Local"? - java

Spring has a class called LocalEntityManagerFactoryBean. Why is this class called "Local"? In what meaning is it local? Is there some RemoteEntityManagerFactoryBean class in Spring as well?

I dont have an authoritative source, however I'm pretty sure that it is "Local" in that it is local to the spring application context used by the application.
Spring doesn't provide a Remote EMF, however other components such as application servers will. For instance JBoss AS (an open source J2EE app server) can manage JPA EMF's and will make it available to your application at runtime, eg over JNDI, refer to the JBoss docs

Related

websphere wasjdbcDataSource to XADataSource

i already setup oracle xadatasource in websphere, and i want get datasource by using spring context lookup jndi , exception happen when i start my app : WasjdbcDataSource incompatible with javax.sql.XADataSource.
how can i solve this?
In a Java EE application server, such as WebSphere Application Server, even though you configure the XA-capable javax.sql.XADataSource, the application (and Spring) should always expect to use it as javax.sql.DataSource. Look in the Spring configuration if there is a way to indicate the expected type of javax.sql.DataSource rather than javax.sql.XADataSource. The XADataSource API is intended only for the application server's own internal use in order to accomplish two-phase commit. The user always interacts with it as javax.sql.DataSource, and gains the ability to enlist multiple resources in a single global transaction.

Inject of remote EJB interface into external module

I have an EAR application with three modules:
beans are in "app-ejb" module
remote interfaces are in "app-remote"
web services are in "app-war"
app-ejb and app-war use app-remote as library.
all are packaged in "app.ear".
This is working fine, but now I have to use the same beans outside the EAR application, and injection is not working.
I have in app-ejb:
#Stateless
#LocalBean
public class Services implements ServicesRemote {
[...]
}
and his remote interface in app-remote:
#Remote
public interface ServicesRemote {
[...]
}
In my app-war I can inject the remote bean without problem:
#Stateless
#LocalBean
public class UseServices {
#EJB
private ServicesRemote services;
[...]
}
Anyway in my external ejb application, deployed as stand-alone and using the same ejb-remote as library, if I try to inject the same EJB like this:
#Stateless
#LocalBean
public class UseServicesFromAnotherApp {
#EJB
private ServicesRemote services;
[...]
}
Glassfish (4.1) give me an error "Class [ Lcom/[...]/ServicesRemote; ] not found".
Is this expected? How can I inject the remote bean correctly?
Injection doesn't work with remote interfaces. Beans that are "injectable", live inside container's JVM and are available for injection to other beans inside the same application. The same holds true for accessing beans in another application in the same container, although applications may live in the same JVM. Since remote methods are originated from another JVM or another application, injection is not possible. You must use JNDI lookup instead to get a reference to a remote bean.
As a matter or personal taste, I would stay away from EJB Remote interfaces, and instead I would use another "remoting" technique such as REST.
The problem was probably generated by a number of hot deploys, made glassfish unstable.
When I restarted glassfish my code start to work properly (it's actually still working).
Sorry for posting here without trying to restart glassfish first.

JavaEE 7: EJB jndi-name without interface

I use GF4 server and in its log I have:
Portable JNDI names for EJB com.test.cms.svr.web.Service2:
[java:global/com.test.cms.svr.web_1.0.0/com.test.cms.svr.web.Service2,
java:global/com.test.cms.svr.web_1.0.0/com.test.cms.svr.web.Service2!com.test.fw.svr.web.bundle.ComponentService]]]
My questions:
Why are there two jndi names - with interface and without interface?
Why can I get bean only using jndi-name with interface even when EJB is only local?
Why are there two jndi names - with interface and without interface?
This is an EJB 3.1 feature called portable JNDI names. Here is nice explanation from this blog:
Client applications need to use global JNDI name to lookup an EJB. All
along the ejb specifications had been silent about portability of such
global jndi names. This allowed each vendor to assign a global jndi
names to EJBs in a vendor specific way. This meant that the client
code that performed a lookup using global JNDI names were inherently
non portable across appserver vendor implementations.
EJB 3.1 solves the above problem by mandating that every container
must assign (at least one) well defined global JNDI names to EJBs. The
general syntax of a (portable) global JNDI name of an EJB is of the
form:
java:global/[<application-name>]/<module-name>/<bean-name>!<fully-qualified-bean-interface-name>
In addition to the above name, if the EJB exposes just a single client
view (that is it implements just one interface or the no interface
view), the container is also mandated to map the bean to
java:global/[<application-name>]/<module-name>/<bean-name>
Where
<application-name> defaults to the bundle name (.ear file name) without the bundle extension. This can be overridden in
application.xml. Also, is applicable only if the
bean is packaged inside a .ear file.
<module-name> defaults to bundle name (.war or .jar) without the bundle extension. Again, this can be overridden in ejb-jar.xml.
<bean-name> defaults to the unqualified class name of the bean. However, if #Stateful or #Stateless or #Singleton uses the name
attribute, then the value specified there will be used as the bean
name.
There is some additional GlassFish-specific information in the GlassFish EJB FAQ.
Why can I get bean only using jndi-name with interface even when EJB is only local?
I guess you mean a lookup from another EJB or module in the same web application inside the same JVM. Otherwise this shouldn't be possible without a #Remote interface. Here are two statements from the GlassFish EJB FAQ:
I have an EJB component with a Local interface. Can I access it from an Application Client or a stand-alone java client ?
If the EJB component is running within the server, no. The EJB Local
view is an optimized invocation path that uses call-by-reference
semantics. It is only available to web components and EJB components
that are part of the same application as the target EJB component.
To access EJB components that are running in the server from an
Application Client or stand-alone java client, you'll need to use
either a Remote 3.x Business interface, a 2.x Home interface, or web
services.
One alternative, if using GlassFish v3, is to use the EJB 3.1
Embeddable API. This allows a Java SE program to directly execute EJB
components within the same JVM, without using a server process.
I have an EJB component with a Local interface. Can I access it from a web component in a different application?
No. The EJB specification only requires access to an EJB component's
local EJB interface from within the same application in the same JVM.
One option is to package the ejb-jar in the same .ear as the .war. A
second option, if using GlassFish v3, is to package the EJB component
directly within the .war.
The GlassFish EJB FAQ also contains alot more detailed information about this topic.
See also:
Looking up an EJB dynamically
Consuming local EJB, in the same Container but different ears

Packaging EJBs in Java EE server

I have deployed an enterprise app in an EAR and a standalone web app in WAR (out side of the EAR) to the same Java EE server.
Question is can I access the local interface of the session bean in the EAR from the standalone WAR? if so can I use dependency injection (DI)?
Section 3.2.2 of the EJB 3.1 specification explicitly states that this is not portable:
Access to an enterprise bean through
the local client view is only required
to be supported for local clients
packaged within the same application
as the enterprise bean that provides
the local client view. Compliant
implementations of this specification
may optionally support access to the
local client view of an enterprise
bean from a local client packaged in a
different application. The
configuration requirements for
inter-application access to the local
client view are vendor-specific and
are outside the scope of this
specification. Applications relying on
inter-application access to the local
client view are non-portable.
In general, the solution will require at a minimum:
Some mechanism for allowing both the EAR and WAR class loaders to have visibility to the same interface class.
Some mechanism for looking up a local interface from another application. For example, java:global.
The answer anyway to both your questions is yes.
Since both the ear and war are in the same JVM, a local interface can be used. To get an instance of the session bean, you would use the global JNDI name of said bean to do either a JNDI lookup or use with the mappedName property on the #EJB annotation. Those names are standardized via the following pattern:
java:global[/<app-name>]/<module-name>/<bean-name>[!<fully-qualified-interface-name>]
Lookup would thus be if the name of your ear is my_app, your bean is MyBean.java and its local interface is com.foo.SomeBeanLocal:
InitialContext ctx = InitialContext();
SomeBeanLocal someBean = (SomeBeanLocal) ctx.lookup("java:global/my_ear/SomeBean/com.foo.SomeBeanLocal");
Injection would be:
public SomeManagedClass {
#EJB(mappedName="java:global/my_ear/SomeBean/com.foo.SomeBeanLocal")
SomeBeanLocal someBean;
}
There are two catches however:
Non-standard naming
Older Java EE implementations (e.g. JBoss AS 5.1, Glassfish 2, Websphere) used their own naming pattern. E.g. JBoss AS 5.x would use:
<app-name>/<bean-name>/local|global
E.g. with the same names as the previous example, the global JNDI name of that bean in JBoss AS 5.1 would be:
my_app/MyBean/local
As said, other old application servers might use other names.
Startup-order
Especially with injection you have to assure somehow that the application you want to inject from has been started before the application you want to inject into. I.e. in your case that the EAR has been started before the standalone WAR. There are no standard mechanisms for this. You might be just lucky that it happens to be in the right order for you. This order might be influenced by time-stamps, alphabetical order of application names, or something else entirely.
JBoss AS for example uses <depends> tags in many of its proprietary configuration files, which is perfectly suited for this although it can be hard to find out what exactly you need to depend on (the syntax can be very cryptic).

Java EJB interface

I have been working through this tutorial. Halfway though it creates an interface and facades for an EJB. Can anyone tell me when I reference the interface using the #EJB annotation, where does it actually make the link between the interface and the actual enterprise java bean itself.
Thanks for the help.
~ Kyle.
It is AFAIK not mandated by the J2EE specification how this is actually solved or implemented by the application server. The most common solution is that the app server uses its own mapping between bean class names and JNDI names, so that depending on the bean class name, it is bound to a specific JNDI path when deploying the application and the same class name -> JNDI path conversion is used for injecting the EJB reference on the "client side".
It will be done inside the EJB container.
When you add this annotation, you'll actually be telling the IoC container of your application server which implementation of the given EJB you want.

Categories