I’m developing Java EE application which has many integrations with other services. All integrations are done over remote EJB beans. So currently I have 3 or 4 EJB projects which are deployed as EARs on WebSphere to serve as mocks (since I don’t have access to real services in my development environment). What I want to do is to combine all of those mocks into one EAR package so I can have a single configuration page for mocks (return values, exceptions, etc.). So I made generalMock.ear application. The problem is now that EJB binding name is different than before.
For example the real application uses following binding name:
binding-name="java:global/company-app-calculator-ear/company-app-calculator-ejb/CalculatorSb!com.company.beans.app.calculator.CalculatorSbRemote"
But now the binding name looks like this:
binding-name="java:global/general-mock-ear/company-app-calculator-ejb/CalculatorSb!com.company.beans.app.calculator.CalculatorSbRemote"
Is there a way to change the global binding name? I have tried to create file “ibm-ejb-jar-bnd.xml” and add it to EJB mock’s META-INF folder where I wanted to change the binding name but I’s not working.
Here is the content of my “ibm-ejb-jar-bnd.xml” configuration file:
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar-bnd xmlns="http://websphere.ibm.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-ejb-jar-bnd_1_0.xsd"
version="1.0">
<session name="CalculatorSb">
<interface
binding-name="java:global/company-app-calculator-ear/company-app-calculator-ejb/CalculatorSb!com.company.beans.app.calculator.CalculatorSbRemote"
class="com.company.beans.app.calculator.CalculatorSbRemote"/>
</sescomon>
</ejb-jar-bnd>
I'm using IBM WebSphere 8.5 running on Java 1.6 EE.
The format of the java: names are defined by the Java EE and EJB specifications for portability across providers. In general, the specification does not provide a way to override these names, nor does WebSphere.
The <interface> element in the ibm-ejb-jar-bnd.xml file may be used in traditional WebSphere to define where an EJB is bound in the server context root (not a java: location), in addition to the java: location. The binding-name value must not start with java:.
Basically, you would need to change the name of your mock EAR, or set the application name in application.xml, but it seems that would only solve the problem for one of the EJB modules in your mock application.
Perhaps consider using EJB references instead of performing direct lookups in java:global. This would allow your application to always lookup the EJB reference name, which would never change. You would just need to bind the EJB reference name to either the real name or mock name depending on the environment.
Have you tried using the simple-binding-name for EJB by adding a file META-INF/ibm-ejb-jar-bnd.xml? It will look something like this for:
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar-bnd
xmlns="http://websphere.ibm.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-ejb-jar-bnd_1_0.xsd"
version="1.0">
<session simple-binding-name="ejb/session/myEJBBean" name="myEJBBean">
</ejb-jar-bnd>
Now client can connect to above EJB by mapping ejb rerference to the simple binding name.
<ejb-ref name="myRef" binding-name="ejb/session/myEJBBean"/>
Related
I was needing to use JPA in standalone application, so I've found the example http://tomee.apache.org/latest/examples/jpa-hibernate.html as starter.
They create EJB Context via
final Context context = EJBContainer.createEJBContainer(p).getContext();
Then there's a log line:
INFO - Enterprise application "/Users/dblevins/examples/jpa-hibernate" loaded
You need to know that application name to wizard out the search string for lookup:
context.lookup("java:global/jpa-hibernate/Movies");
What makes me worry that I've found out no information on where those 'jpa-hibernate' part comes from. It either comes from artifact id, or, even worse, from the current directory name, which makes the code using it terribly dependend on context, that the developer doesn't control.
I've totally find to google out how to specify that application name so that I could use lookup that will work no matter who invokes my code and where it is copied.
How can I configure this application name?
The Embedded EJB container used in this unit test example allows to run EJBs outside a Java EE container. A good introduction/tutorial can be found here: https://docs.oracle.com/javaee/7/tutorial/ejb-embedded002.htm
It supports the same configuration files as regular EJB-jars, namely it supports the ejb-jar.xml configuration file (the module deployment descriptor). It is possible to configure the module name there, e.g.
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd"
version="3.1">
<module-name>myapp</module-name>
</ejb-jar>
This file needs to go into the jar's META-INF directory.
I have a portal server. There are number of portlets installed. I have environment configs file which is same for all portlets installed on that app server. I am using apache commons-configuration for managing from the configuration files.
Right now, each portlet/component build their own EnvConfiguration bean from these files. Obviously this is eating up more memory. I want to separate out the creation of EnvConfiguration bean and share it across all the portlets. Basically, I want to create only one bean per app server.
What are the best possible ways to do this? And how will this common beans(s) injected into the needed components?
Edit: This is a liferay application and non EAR model
Thanks
Sundar
You can use the parentContextKey web.xml param.
Here is a blog post explaining how : http://spring.io/blog/2007/06/11/using-a-shared-parent-application-context-in-a-multi-war-spring-application/
The idea is to package and declare the beans you want to share in a common jar (if you use Tomcat, you can put it in the server lib folder). The beans are declared in a file called beanRefContext.xml (default name, can be changed), with an id. Then you add the param "parentContextKey" in the web.xml of your webapps with the id previously mentionned.
We have a multimodule Java EE 5 project running on Weblogic 10.3.x. One module has the EJBs and our batch processor is running from the web-module. Since we don't have CDI in JavaEE5, we have to do a JNDI-lookup on the EJBs. The EJBs are defined with #Stateless on the class and #Remote on the interface.
I have succeeded accessing the EJBs by looking the following string:
ejb/batchService#com.example.service.batch.ejb.BatchServiceRemote
However, I belive this is highly platformdependent, and I suspect I should have put something inside the web.xml and probably into the weblogic.xml at least in the web-module - maybe even in the EJB module...
Could anyone enlighten me how to do this propperly? Or is this the best way available?
JNDI format of local bean is
java:comp/env/BeanClassName
JNDI format for remote bean is
mappedName#com.package.BeanClassName
for
#Stateless(mappedName = "mappedName")
public class BeanClassName {
PS. This format supported by WebLogic 10.3. Behaviour of another application servers may be differentю
Prior to EJB 3.1 / EE 6, there are no standardized lookup strings for EJBs. Since they're not standardized, hard-coding the actual binding name of the EJB does make your project product-specific.
The best solution is to create another level of indirection: declare an <ejb-local-ref> in web.xml (or as #EJB/#EJBs on a servlet or other component class), and then use java:comp/env/xyz to lookup the ref. Then, use platform-specific bindings for the EJB ref.
I have a need to build 1 restful web service using weblogic. This web service will have parameters to select a what data the service should return. Like 'customer', or 'product'.
Now I want to deploy the 'customer' and 'product' code as a separate deployable applications, so that I can add or remove new code without redeploying all the code each time there is a change.
So I want one generic webservice to call this business logic.
My question is, what is the best way to structure this? Can I deploy separate EJBs for my business logic and have the web service invoke the EJBs based on the passed parameters?
Or should I have the business components as a shared library and call them that way? I am looking for a way to get the best performance.
I will have about 20 different business modules written by other programers. Like I said I don't want all the modules in the same EAR or WAR file. They need to be separately deployable.
Any thoughts?
WebLogic 10.3.4 includes new Java EE6 API support including JAX-RS 1.1 with Jersey. We recently did a webcast on this functionality and Webcast #4 covers JAX-RS. Here's the link: http://www.oracle.com/technetwork/middleware/weblogic/learnmore/weblogic-javaee6-webcasts-358613.html There is also an example application on this called Oracle Parcel Service and you can download the code here: https://www.samplecode.oracle.com/sf/projects/oracle-parcel-svc/.
If you use JAXB you can marshall from JSON and XML into the same Java object. The challenge here is that the JAXB generated classes are not serializeable by default so if you wanted to access a remote EJB from the JAX-RS service then you would have a problem.
Since you can't have the modules in the same EAR, there is another option. You could possibly use Java EE shared libraries. Then you could deploy your EJB's as a Java EE Shared library and reference that library in your REST client. Here is an example:
In your EJB module, include something like the following in your manifest:
Extension-Name: ops-util
Implementation-Title: OPS 2.0 Utils Library EXAMPLE_ONLY
Implementation-Vendor: Oracle
Implementation-Vendor-Id: com.oracle
Implementation-Version: 2.0.1
Specification-Title: Oracle Parcel Service 2.0 Utils Library
Specification-Vendor: Oracle
Specification-Version: 2.0
Then reference the shared library in weblogic.xml (WAR) or weblogic-application.xml (EAR):
<wls:weblogic-application
xmlns:wls="http://www.bea.com/ns/weblogic/weblogic-application"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/javaee_5.xsd http://www.bea.com/ns/weblogic/weblogic-application http://www.bea.com/ns/weblogic/weblogic-application/1.0/weblogic-application.xsd">
<!-- server-version: 10.3 -->
<wls:library-ref>
<wls:library-name>ops-util</wls:library-name>
<wls:specification-version>2.0</wls:specification-version>
<wls:implementation-version>2.0.1</wls:implementation-version>
<wls:exact-match>false</wls:exact-match>
</wls:library-ref>
</wls:weblogic-application>
I usually use Commons Configuration for manage my applications configs. I have used properties files configuration. Now I'm interested in using a JNDIConfiguration but I'm not able to understand how this works reading the documentation or googling it.
Contextualizing, I'm working in webapps running in an JBoss AS.
Where will be the properties stored? In a file? some tables in a database?
I will be grateful for any guidance at this level even if it comes in shape of links where I can read some valuable information about it.
As a final note my goal is to free me of linking a file with a hardcoded path for my properties, but also don't force me to have my config in database tables. If you have any suggestions on how to do that in some other way be free to share.
JNDIConfiguration looks up the configuration data on a JNDI server (in your case, the JBoss JNDI server). However, you still need a way of getting that data into the JNDI server in the first place, and Commons-Configuration won't help you with that.
It sounds to me that JNDI isn't what you want, it's just pushing the problem around a bit. JBoss still needs to store the configuration data somewhere, so you'll still have the same basic problem.
If you don't want hard-coded file paths, and you don't want a database, then I suggest you pass in the location of the properties file via a system property, e.g.
java -Dmy.config.path=/my/config.properties com.MyClass
Then pass that location to Commons Configuration and let it load your config that way. No hardcoded-paths, no database.
I don't know much about Commons Configuration and JNDIConfiguration, but if what you want is a set of key/value pairs, the standard way of doing this as per the Java EE specs, is to use env-entry in the web.xml or ejb.xml.
<env-entry>
<env-entry-name>maxExemptions</env-entry-name>
<env-entry-value>10</env-entry-value>
<env-entry-type>java.lang.Integer</env-entry-type>
</env-entry>
(example taken from JBoss web conf. reference.)
These values are bound in the JNDI so they can be looked up or injected.
Where will be the properties stored? In a file? some tables in a database?
As #ewernli mentioned, the Java EE way to add entries in the JNDI tree is to use env-entry in your deployment descriptor(s).
Now, if you don't want to repeat the same env-entry in several deployment descriptors, then there is a service for specifying global JNDI bindings: JNDIBindingServiceMgr.
Below, the provided jboss-service.xml example:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE server PUBLIC "-//JBoss//DTD MBean Service 4.0//EN"
"http://www.jboss.org/j2ee/dtd/jboss-service_4_0.dtd">
<server>
<mbean code="org.jboss.naming.JNDIBindingServiceMgr"
name="jboss.tests:service=JNDIBindingServiceMgr">
<attribute name="BindingsConfig" serialDataType="jbxb">
<jndi:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jndi="urn:jboss:jndi-binding-service:1.0"
xs:schemaLocation="urn:jboss:jndi-binding-service:1.0 resource:jndi-binding-service_1_0.xsd"
>
<jndi:binding name="urls/jboss-home">
<jndi:value type="java.net.URL">http://www.jboss.org</jndi:value>
</jndi:binding>
<jndi:binding name="hosts/localhost">
<jndi:value editor="org.jboss.util.propertyeditor.InetAddressEditor">
127.0.0.1
</jndi:value>
</jndi:binding>
<jndi:binding name="maps/testProps">
<java:properties xmlns:java="urn:jboss:java-properties"
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
xs:schemaLocation="urn:jboss:java-properties resource:java-properties_1_0.xsd">
<java:property>
<java:key>key1</java:key>
<java:value>value1</java:value>
</java:property>
<java:property>
<java:key>key2</java:key>
<java:value>value2</java:value>
</java:property>
</java:properties>
</jndi:binding>
</jndi:bindings>
</attribute>
<depends>jboss:service=Naming</depends>
</mbean>
</server>
If this is not what you are looking for, then I don't understand what you're looking for :) In that case, you should maybe clarify it.