Unclear EJB bean JNDI name under Weblogic - weblogic

I made a small example using weblogic 10.3.6 and EJB 3.0. Define SimpleService class, define weblogic-ejb-jar.xml in order to map SimpleService class to JNDI name, pack it as EJB component in EAR file and deploy on server. Deployment is successful and I can see ejb bean with name SimpleServiceBean. After that using standalone application connect to webloigc server through InitialContext with all necessary environment attributes I try to lookup that bean. I assume that it will be available under name ejb/SimpleService but can't found it under that name and only after I was looking through a JNDI tree name I found out that it available under name SimpleService#ds/base/ejb/SimpleService. Help me to understand what is going on? How should I configure ejb bean in order that it will be available under ejb/SimpleService as it described in the official weblogic manual? Or maybe it's a correct JNDI name for the EJB bean?
My classes and configs are:
ds.base.ejb.SimpleServiceBean:
#Stateless(mappedName = "ServiceBean")
#TransactionAttribute(NEVER)
#ExcludeDefaultInterceptors
#Remote(SimpleService.class)
public class SimpleServiceBean implements SimpleService {
...
}
weblogic-ejb-jar.xml
<weblogic-ejb-jar>
<weblogic-enterprise-bean>
<ejb-name>ServiceBean</ejb-name>
<jndi-name>ejb/ServiceBean</jndi-name>
<enable-call-by-reference>True</enable-call-by-reference>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>
application.xml:
<application>
<display-name>web-app-ear</display-name>
<module>
<ejb>app-ejb-1.0-SNAPSHOT.jar</ejb>
</module>
</application>
Then try to get it from standalone:
InitialContext context = new InitialContext(env);
SimpleService simpleService = (SimpleService)
context.lookup("SimpleService#ds/base/ejb/SimpleService");
assert simpleService != null

there is a good FaQ about the global portal JNDI names on glassfish.org http://glassfish.java.net/javaee5/ejb/EJB_FAQ.html#SessionBeanGlobalJNDINameAssignment
It is best practise NOT to assign a jndi name but rely on the ones defined since EE 5 (e.g. SimpleService#ds/base/ejb/SimpleService)
If you add the jndi-name configuration to your weblogic-ejb-jar.xml you could actually make it available as ejb/ServiceBean but you also have to define it "old school" style in ejb-jar.xml. More on the weblogic-ejb-jar.xml can be found http://docs.oracle.com/cd/E23943_01/web.1111/e13719/ejb_jar_ref.htm
There is also a good overview about the dd in the orcl docs.
http://docs.oracle.com/cd/E23943_01/web.1111/e13719/understanding.htm#EJBPG129
Assuming, that you are working with 10.3.x server version ...

Use this.
#Stateless(mappedName="UserFacade")
public class UserFacadeImpl {
//......
}
Properties p=new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
p.put(Context.PROVIDER_URL,"t3://localhost:7001");
InitialContext ctx=new InitialContext(p);
userFacade=(UserFacade)ctx.lookup("UserFacade#com.webservices.facade.UserFacade");
hope it helps.

Related

Servlet 3.0 and JAX-RS

I've found conflicting answers to this question and I've failed to successfully run an example.
Can JAX-RS be implemented using Servlet 3.0 (in particular, Tomcat 7) with annotations, only, without having to implement another Servlet Container?
If no, please explain why the following quote from this book is either, incorrect or I'm interpreting it, wrong.
Because this example deploys within a Java EE application server or
standalone Servlet 3.x container, all we need is an empty web.xml
file. The server will detect that an Application class is within your
WAR and automatically deploy it. (RESTful Java with JAX-RS 2.0, Bill Burke)
To clarify what I don't need help with... I've, successfully, implemented JAX-RS in Tomcat 7 with Jersey using a web.xml, so, I don't need any explanation of how to do so. Also, I'm fully aware that other Java EE/Servlet Containers (TomEE, Glassfish, Jersey, Websphere, etc...) are all JAX-RS aware out of the box. I just need to know if I'm chasing my tail trying to get Tomcat 7 (Servlet 3.0) to work with JAX-RS without adding a Servlet Container and without web.xml entries.
In a Servlet environment, Jersey runs as a servlet or servlet filter. No way around that. So how does it work without declaring it in the web.xml? Two main components to this functionality
Programmatic registration of Servlet components (i.e. servlets and fitlers). You can do a Google search, and you should find some hits of examples.
Servlet pluggability introduced in Servlet 3.x. How it works is you implement a ServletContainerInitializer, list that implementation in a file named javax.servlet.ServletContainerInitializer, and put that file in the META-INF/services directory of the jar. The servlet container should scan jars looking for this file. When it finds on, it sees the implementation, finds the implementation, instantiates it, then calls it onStartup method.
Jersey has such an implementation of the SevletContainerInitializer in the JerseyServletContainerInitializer. This class is located in the jersey-container-servlet jar. So you need this jar for this to work. If you look at this method, this is where you will see the programmatic registration of the ServletContainer (the same one that yo would declare in the web.xml
But that's not all. We still need some way of configuring our application, at the least declare the servlet mapping. That's where the Application class and the #ApplicationPath annotation come in. We would extend the Application class and and annotate the #ApplicationPath("/path") where "path" is the same as the servlet mapping in the web.xml
#ApplicationPath("/api")
public class MyApplication extends Application {}
This is standard JAX-RS. With Jersey normally instead of an Application class, we use a ResourceConfig class (which is a subclass of Application)
#ApplicationPath("/api")
public class MyApplication extends ResourceConfig {
public MyApplication() {
packages("package.to.scan");
}
}
You can see more about Jersey deployment options in a Servlet 3.x environment, here.
It should also be noted, that a Java EE server has the JAX-RS implementation, so we only need to add the javaee-api jar to our application as provided dependency. But in a servlet container, we need to provide our own implementation, Jersey being such an implementation.
If you are using Maven, the main dependency you'll need is this one
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey2.version}</version>
</dependency>
This will pull a bunch of other jars in. You you aren't using Maven, then you can download all the jars here (the JAX-RS 2.0 RI bundle), and put all those into your application.
See Also:
How to use Jersey as JAX-RS implementation without web.xml?

No component found with scheme : jetty

So I scoured the message boards and see some people that have bumped into this issue but usually it was due to a missing dependency in the POM file.
My case:
Running JBoss Fuse jboss-fuse-6.1.0.redhat-379
Apache Camel 2.14.1
Spring 3.2.8_RELEASE_1
Have the camel-jetty dependency in my POM file
Installed the feature in Karaf. Verified the feature is there in
OSGI list and feature list.
jetty / 8.1.14.v20131031
Runs fine within eclipse.
So I have a context with the following rest configuration:
<camelContext id="FIRST-CAMEL-CONTEXT" xmlns="http://camel.apache.org/schema/spring" streamCache="true">
<restConfiguration component="jetty" bindingMode="json" port="8881" host="0.0.0.0">
<dataFormatProperty key="prettyPrint" value="true"/>
</restConfiguration>
<rest path="/search" consumes="application/json" produces="application/json">
<description>Get Search Results</description>
<!-- this is a rest GET to find all users -->
<post uri="/SearchHotels" outType="HotelsEnvelope.Response" type="HotelsEnvelope.Request">
<description>Hotels</description>
<to uri="bean:searchRequest?method=ReturnHotels(Exchange,${body},${headers})"/>
</post>
</rest>
.....
</camelContext>
the beans defined above as such:
<bean id="searchRequest" class="ICEPricelineSVC.SearchRequest" />
In the Bean I basically create a context and then send a request to a third party service like so:
CamelContext context = new DefaultCamelContext();
ProducerTemplate template = context.createProducerTemplate();
.....
String url = String.format("jetty:http://api.rezserver.com/api/hotel/getResultsWithCacheV2?function_type=get&format=xml&refid=%s&api_key=%s&currency=USD&latitude=%s&longitude=%s&radius=%s&check_in=%s&check_out=%s&adults=2&children=0&rooms=1&nearby=0&recent=0&promo=1&sort_by=most_popular&sort_order=ASC&limit=5000&offset=0&format=xml&function_type=get&poi_name=search&bridgeEndpoint=true&amp;throwExceptionOnFailure=false",supplier.getCredentials().getRefid(),supplier.getCredentials().getKey(), request.getQryLocation().getLat().toString(), request.getQryLocation().getLng().toString(), request.getQryLocation().getRadius().toString(),formatter1.format(dateCheckIn), formatter1.format(dateCheckOut));
Exchange exchange = template.send(url, new Processor() {
public void process(Exchange exchange) throws Exception {
exchange.setPattern(ExchangePattern.InOut);
Message inMessage = exchange.getIn();
Inits.setupDestinationURL(inMessage);
// set the operation name
inMessage.setHeader(Exchange.HTTP_METHOD, org.apache.camel.component.http4.HttpMethods.GET);
}
});
.....
When the producer template sends I get the jetty error.
I have tried various things. One of which is injecting the ApplicationContext in the bean and getting the FIRST_CAMEL_CONTEXT bean to retrieve the context. In that case the request seems to be sent but the exchange returned from the processor is null.
Again, this all works in eclipse. I also noticed that when I deploy the bundle I see it adding the dependencies to the container. Is there a good way to chase this? I have resorted to using the HTPClient for now but would really like to understand why there seems to be a classpath issue when using the producer.
Thanks.
JBoss Fuse 6.1 comes with Apache Camel 2.12.x out of the box. You must use that version as that is the certified and tested version.
JBoss Fuse 6.2 which is the next release comes with Apache Camel 2.14.x and that release has the new rest-dsl.

Difference JNDI configuration between Glassfish and TomEE?

We want to migrate an old application from Glassfish to TomEE. We encounter a problem about JNDI.
When I run the cmd for Glassfish server asadmin list-jndi-entries I get some JNDI entries:
java:global: com.sun.enterprise.naming.impl.TransientContext
UserTransaction: com.sun.enterprise.transaction.TransactionNamingProxy$UserTransactionProxy
com: com.sun.enterprise.naming.impl.TransientContext
OURAPPSERVER-Q2: com.ourcompany.product.OurAppServer
com.sun.enterprise.container.common.spi.util.InjectionManager: com.sun.enterprise.container.common.impl.util.InjectionManagerImpl
ejb: com.sun.enterprise.naming.impl.TransientContext
jdbc: com.sun.enterprise.naming.impl.TransientContext
AppServer: com.sun.enterprise.naming.impl.TransientContext
As you can see, there is AppServer JNDI entry. This entry is bind from our code manually.
try {
InitialContext context = new InitialContext();
context.rebind("AppServer/facede", this);
} catch (NamingException e) {
e.printStackTrace();
logger.severe("Unable to register the service facade bean, "
+ "JPOS will not be able to access services");
}
This code is not working in TomEE. I get some error like:
javax.naming.NameNotFoundException: Name [AppServer/facede] is not bound in this Context. Unable to find [AppServer].
at org.apache.naming.NamingContext.bind(NamingContext.java:899)
at org.apache.naming.NamingContext.rebind(NamingContext.java:225)
It seems like the container can't found context base on AppServer.
I am not a master of JNDI. Then I have checked some documents. The java:comp/env/ is the basic namespace. And "jdbc" for DBCTM DataSource references, "jms" for JMS connection factories, "mail" for JavaMail connection factories, "url" for URL connection factories.
We don't want to change too much on our old application code. It's not use any special features of Glassfish. I want to know how to define a JNDI in a correct way.
Is there anyone could tell me why Glassfish can use AppServer as namespace, but TomEE can't.
Tomcat (then TomEE) is not designed to change JNDI at runtime like it. Saying it simply the best is to not use this pattern but a contextual resource. Inject the resource you desire and that's this resource you change instead of JNDI (which is quite more impacting that it seems)

How to add a Datasource to embedded Weblogic 12

How can I add a datasource configuration file within a embedded Weblogic EJB Container?
As far as I know, this is only possible with a already installed and preconfigured weblogic, instance? Is this correct?
My configuration is the following:
Properties prop = new Properties();
prop.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("datasource.properties"));
EJBContainer container = EJBContainer.createEJBContainer(prop);
Context initialContext = container.getContext();
((MyEJB)initialContext.lookup("MyEjb")).writeInDatabase();
I have not found a lot of documentation on this topic.
http://vineetreynolds.blogspot.com/2012/11/the-embedded-ejb-container-in-weblogic.html
see if this helps, although I cant get stuff to run yet on my end
you are better of being in jpa land, and create a test persistence.xml that basically uses jdbc url/user/pass and not jndi

giving an EJB a JNDI

I have created and EJB with a remote interface:
#Stateless
public class TestSessionBean implements TestSessionRemote
{
public void businessMethod()
{
System.out.println ("***businessMethod");
}
}
I to access it from another component (e.g a servlet) running on the server via:
ic = new InitialContext();
ic.lookup("myEJB");
I am using netBeans 6.5.1 and glassfish v2.
How can I do that?
Thanks,
Ido
actually ejb3 use a default naming convention, wich i've not found a way to get around.
The name for your bean would be something like:
TestSessionBean#package.TestSessionBean
To acess your remote service you can do something like this
InitialContext ctx = new InitialContext();
ctx.lookup(interfaceClass.getSimpleName()+"#"+interfaceClass.getName());
where interfaceClass is the class of your remote interface.
do note you havent defined a remote interface(or local for that matter) for that webserver. you mightnot be able to acess theejb from another context.
As for changing the name that is actually i dont think is possible through anotations. not sure though