I am currently working on a project with multiple ejb and one ejb-jar.xml. I wonder how to share the env-entry from the ejb-jar.xml between the various ejbs.
example :
I have the following ejb-jar.xml
<session>
<ejb-name>MyBeanA</ejb-name>
<ejb-class>com.enterprise.MyBeanA</ejb-class>
<env-entry>
<env-entry-name>myVar</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>some value for my var</env-entry-value>
</env-entry>
</session>
When in the MyBeanA I use :
#Ressource
private SessionContext context;
I can get the value of myVar with the following code :
String myVar = (String) context.lookup("java:comp/env/myVar");
Is there a way to get the value of myVar in another ejb like MyBeanB ?
Hmm. There was supposed to have been a section of the assembly-descriptor where you could do this, but I see now we must have missed that before the spec went final. Shame. Will bring that up in the EG and cross my fingers it isn't too late to fix for EJB.next.
In the meantime if you have an ear, you can declare them in the application.xml and it will be available in java:app/. If you have EJBs in a .war file, you can do it in the web.xml and the EJBs will be able to see them in either java:comp or java:module.
Related
I'm working on EJB application, and i'm trying to use lookup approach but it fails at Runtime moment,
Here my code and configuration :
weblogic.xml
<ejb-reference-description>
<ejb-ref-name>
RechercheClientSMBean
</ejb-ref-name>
<jndi-name>
*****-ejb/RechercheClientSMBean/local
</jndi-name>
</ejb-reference-description>
Local Interface
#Local
public interface IRechercheClientFacade extends Facade {}
Bean Implementation
#Stateless(name="RechercheClientSMBean", mappedName="RechercheClientSMBean")
public class RechercheClientSMBean extends AbstractBean implements IRechercheClientFacade { }
web.xml
<ejb-ref>
<ejb-ref-name>RechercheClientSMBean</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<home>com.*****.***.app.service.common.client.RechercheClientSMBean</home>
</ejb-ref>
Bean Lookup Code
InitialContext ctx = new InitialContext();
iRechercheClientFacade= (IRechercheClientFacade)ctx.lookup("java:comp/env/RechercheClientSMBean");
It results into the following Exception :
weblogic.deployment.EnvironmentException:
The ejb-link 'RechercheClientSMBean' declared in the ejb-ref or ejb-local-ref 'RechercheClientSMBean' in the application module 'pfi.war' could not be resolved. The target EJB for the ejb-ref could not be found. Please ensure the link is correct.
I checked every possible configuration, every naming possibility but i keep getting this same problem.
PS: the project is divided into multiple modules, the lookup method is made from web container.
Many thanks in advance.
Have you tried the following:
ctx.lookup("java:comp/env/ejb/RechercheClientSMBean");
I recently saw a post that explained in JAVA EE, instead of using a .properites file, a better way to specify Configuration Properties is in a web.xml file and then injecting them inside the Class where the properties are needed.
This is my Web.xml
<env-entry>
<env-entry-name>pacakageName.ClassName/number</env-entry-name>
<env-entry-type>java.lang.Integer</env-entry-type>
<env-entry-value>123</env-entry-value>
</env-entry>
<env-entry>
<env-entry-name>country</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>Spain</env-entry-value>
</env-entry>
And in my Java class, when I use the JNDI way I am able to get the value
InitialContext initialContext = new javax.naming.InitialContext();
String countryName = (String) initialContext.lookup("java:comp/env/country");
This works, but when I try to use the new way of using #Resources and injecting the value, the value is not read from the web.xml
#Path("loginService")
public class LoginService{
#Resource() int number;
//constructor and other methods
}
I am using Tomcat 7...Could anyone help me out what I am doing wrong.
I referred this doc:
http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/env_entry/env_entry.html
Your class is not the kind that supports the #Resource annotation. It needs to be a Java EE component, like an EJB for example.
This is because the container is the one that injects the resources, and it only considers components as valid injection targets. Also for this reason the resource must be defined before the container starts, so you can't inject resources that you put into JNDI during runtime.
Make sure you have beans.xml file in WEB-INF folder (this enables CDI) and then change your variable to java.lang.Integer like this:
#Resource(name="pacakageName.ClassName/number")
Integer number;
#Resource(name="country")
String country;
It works fine in Java EE 6 container that supports CDI for example WebSphere Liberty profile
I have a stateless Bean with following heirarchy and present
accountserver , accountserverBean implements accountserver.
with there corresponding ejb-jar.xml and weblogicjar.xml
Then I have my spring Bean with the following
payload.java with corressponding spring.xml
So Inside the spring libs folder I have added account.jar
So how can I call method present in accountserverBean from payload class????
Also I have used the below Code in payload.java
Context ctx=new InitialContext();
accountserver as=(accountserver)ctx.lookup("java:com/accountserver");
But this doesnt work.
Since both are in same context I can call the EJB method
Please provide me with solution
I guess you want to integrate EJB and Spring applications. Did you try this: http://static.springsource.org/spring/docs/2.5.x/reference/ejb.html ?
I'm using persistence API and want to load jdbc URL from web.xml. URL should be a context parameter of servlet. I can't find how to construct EntityManagerFactory not using persistence.xml. May be I should create PersistenceUnit in servlet and set some parameters? Can you give me some short example?
Thank you
you can use method createEntityManagerFactory(String persistenceUnitName, Map properties) of class javax.persistence.Persistence . and insert all your parameters in the map
I personally find it the cleanest way to define a datasource in the servlet container usng JNDI and refer to that from the persistence.xml.
This also solves one configuration issue when migrating from test-uat-prod as I can use the same datasource name on the machines.
Yeah, I know JNDI is not popular, but this works nice and it avoids having to manipulate hte web.xml which is also wrapped in the war.
Whether you use a datasource or not, the JPA configuration goes in the persistence.xml, not in the web.xml. If you want to use JPA, provide a persistence.xml.
Define an init-param in your web.xml that points to your database url. For example, for MySQL, it would be something like this:
<init-param>
<param-name>DB_URL</param-name>
<param-value>jdbc:mysql:///MY_DB</param-value>
</init-param>
Then get this value inside your Web app (in a Servlet) using something like this:
String myDbUrl = getServletConfig().getInitParameter("DB_URL");
In JSP files you can get the value in this way:
String myDbUrl = config.getInitParameter("DB_URL");
You can retrieve any value from the web.xml by using env-entry
<env-entry>
<env-entry-name>dbUrl</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>jdbc:url:goes:here</env-entry-value>
</env-entry>
And in java
try {
Context ctx = new InitialContext();
String dbUrl= (String) ctx.lookup("java:comp/env/dbUrl");
//... create your connection
} catch (Exception e ) {
}
The Java EE specification states that an EJB injection like this:
#EJB MyInterface myBean;
will create en entry in the Enterprise Naming Context, viz. java:comp/env/<FQN>.MyInterface/myBean. It is up to the deployer to bind this context entry to a real value and to inject this value in the myBean field.
Now I have the feeling I am missing something here:
Why is the context entry necessary? An instance of the requested EJB will be injected, so why is the entry in the context needed? Why does the injection has to happen via the context entry?
All the received answers did not address the issue: why is an ENC entry needed if the injection annotation gives enough information to resolve the injection (so my first thought was that it was redundant).
The answer is that the injection can be overridden in the deployment descriptor. This is because the EJB standard defines developer roles.
It assumes that the "bean provider" can request an injection, even provide default values. But the "application assembler" can override these values. The "bean provider" is assumed to use annotations or XML, and the "assembler" is assumed to mainly use the XML.
That is why the EJB standard defines this relation between the ENC and an injection.
I think if you need to inject an Stateful Session Bean you gonna need some context that knows the relation between your EJB instance and some previously injected EJB dependency (to that instance).
It is to allow you lookups by somehow obtained string.