Is it possible to query/browse the JNDI tree in WebSphere Liberty? - java

I have a EJB with a remote interface that I want to access from a client. I have difficulties to build the string for the JNDI lookup. Is there a command line tool which shows all register enterprise beans in the naming service? Or can I see this in a log file?
The JNDI name should look like this:
corbaname:localhost:2809#ejb/global/MyApp/MyModule/EJBName!full.package.remote.interface.Name
I’m also not really sure if my app and module name in the string is correct.

As far as I know there is no way to dump the JNDI namespace on WebSphere Liberty (there is a way to do this in WebSphere traditional).
The easiest way to check what JNDI name your EJBs are registered at, is to check the messages.log file. In the messages.log file you should see some CNTR0167I messages which indicate where the server has bound your EJBs. The messages.log file can be found in ${server.config.dir}/logs/messages.log.
Example EJB binding message:
CNTR0167I: The server is binding the com.example.DatabaseBean interface of the DatabaseBean enterprise bean in the TestProject.war module of the TestProject application. The binding location is: java:global/TestProject/DatabaseBean!com.example.DatabaseBean
For more info, check out the IBM doc:
Using enterprise JavaBeans with remote interfaces on Liberty

Related

Not able to access JNDI Url context from Spring boot application deployed in WAS Liberty server

I have deployed an spring boot web application in WAS Liberty server (WebSphere Application Server Version 8.5.5.9 Liberty Profile).
I have a JNDI url entry added in server.xml which is given below but one of my class in api is not able to access it.
<jndiURLEntry jndiName="url/SSOService" value="http://ssoserver.dev.intranet/SSOService/SSOFacade" />
I found one weird thing in Liberty is that whenever I add java:comp/env/ to any of the JNDI entry , application is not able to pick it and getting javax.naming.NameNotFoundException:
I fixed the datasource issue by not adding the prefix, but the above URL is used in only of the api which is not in my control.
So how can we enable java:com/env prefix in Websphere Liberty server ?
or is there any alternative available to make this working ?
When you define a JNDI URL entry in the following way:
<jndiURLEntry jndiName="url/SSOService" value="..."/>
It will make the java.net.URL available literally at the url/SSOService name (i.e. no sort of java: prefix). Looking up a JNDI entry from this location is known as a "direct lookup", because you are looking something up that was defined directly in server configuration.
If you want to register this in the java:comp/env/ namespace, you must define a "resource reference", which will create a binding from the server-defined entry to a java:comp/env/ entry. A resource reference can be defined annotatively or via web.xml.
Here is how you can define an annotative resource reference:
#Resource(lookup="url/SSOService", name="url/SSOServiceRef")
URL ssoServiceURL;
In this example, we're saying:
Perform a direct lookup of url/SSOService
Bind that object to java:comp/env/url/SSOServiceRef

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

Location of JNDI file

Since I am new to EJB, I do not know where to search for the JNDI file of an EJB 3.0 project. I am told that in order to access the EJB classes, we need to lookup the class using the JNDI. So can anyone please suggest where do I usually find the JNDI file for an EJB project?
Note : Since EJB 3.0 is used, the concept of ejb-jar.xml is not used. So please suggest.
Thanks!
there are is no JNDI files, it allow to find objects via the name
there is no JNDI file.but the JNDI names can be found for the EJBs in weblogic server for EJB 2.0. on the other hand, for EJB 3.0, the JNDIs can be found in web.xml file

How do I have multiple datasources with the same JNDI name in JBoss?

So, I have a situation where I will be deploying multiple ear files, each of which I need to configure with a different database (potentially).
Right now I have a *-ds.xml file that is deployed in JBoss, with a JNDI name that all my portlets and servlets use to look up the database connection. If I deploy more than one ear file with a *-ds.xml file that points to a different database, but with the same JNDI name, the deployment barfs. Shouldn't JNDI be more modular to prevent naming collision when deploying different application to isolate them.
It will take quite some time to change my lookup in the code, so is there a way to deploy that will work? The only other idea I had would be to set a JNDI property as the value for the datasource name to look up, and then look up that JNDI property first and retrieve the datasource based on the retrieved "key." This seems kind of hackish to me...
You can have the different data source defined on the application server with different name (on the server namespace) and then map it to a resource-ref name (this time component namespace, so each application can have its own one) via the deployment xml file.
For JBoss prior as7: https://community.jboss.org/wiki/HowDoICreateAResourceRef for as7: https://community.jboss.org/message/629666

Help configuring JNDI with embedded JBoss in Tomcat 5.5.x

When I try the following lookup in my code:
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
return (DataSource) envCtx.lookup("jdbc/mydb");
I get the following exception:
java.sql.SQLException: QueryResults: Unable to initialize naming context:
Name java:comp is not bound in this Context at
com.onsitemanager.database.ThreadLocalConnection.getConnection
(ThreadLocalConnection.java:130) at
...
I installed embedded JBoss following the JBoss wiki instructions. And I configured Tomcat using the "Scanning every WAR by default" deployment as specified in the configuration wiki page.
Quoting the config page:
JNDI
Embedded JBoss components like connection pooling, EJB, JPA, and transactions make
extensive use of JNDI to publish services. Embedded JBoss overrides Tomcat's JNDI
implementation by layering itself on top of Tomcat's JNDI instantiation. There are a few > reasons for this:
To avoid having to declare each and every one of these services within server.xml
To allow seemeless integration of the java:comp namespace between web apps and
EJBs.
Tomcat's JNDI implementation has a few critical bugs in it that hamper some JBoss
components ability to work
We want to provide the option for you of remoting EJBs and other services that can > be remotely looked up
Anyone have any thoughts on how I can configure the JBoss naming service which according to the above quote is overriding Tomcat's JNDI implementation so that I can do a lookup on java:comp/env?
FYI - My environment Tomcat 5.5.9, Seam 2.0.2sp, Embedded JBoss (Beta 3),
Note: I do have a -ds.xml file for my database connection properly setup and accessible on the class path per the instructions.
Also note: I have posted this question in embedded Jboss forum and seam user forum.
Thanks for the response toolkit.... yes, I can access my datasource by going directly to java:jdbc/mydb, but I'm using an existing code base that connects via the ENC. Here's some interesting info that I've found out ....
The above code works with JBoss 4.2.2.GA and here's the JNDI ctx parameters being used:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces:
org.jboss.naming:org.jnp.interfaces
The above code works with Tomcat 5.5.x and here's the JNDI ctx parameters being used:
java.naming.factory.initial=org.apache.naming.java.javaURLContextFactory
java.naming.factory.url.pkgs=org.apache.naming
The above code fails with Embedded JBoss (Beta 3) in Tomcat 5.5.x with the above error message.
java.naming.factory.initial=org.apache.naming.java.javaURLContextFactory
java.naming.factory.url.pkgs=org.apache.namingThe above code fails with the above error using JBoss Embedded in tomcat 5.5.x
Anyone have any thoughts I what I need to do with configuring embedded JBoss JNDI configuration?
java:comp/env is known as the Enterprise Naming Context (ENC) and is not globally visible. See here for more information. You will need to locate the global JNDI name which your datasource is regsitered at.
The easiest way to do this is to navigate to JBoss' web-based JMX console and look for a 'JNDIView' (not exactly sure of the name - currently at home) mbean. This mbean should have a list method which you can invoke, which will display the context path for all of the JNDI-bound objects.
I had some similar issue with Jboss Embedded and i finally fix playing in the file:
test-Datasource-ds.xml
adding
<mbean code="org.jboss.naming.NamingAlias" name="jboss.jmx:alias=testDatasource">
<attribute name="FromName">jdbc/Example DataSource</attribute>
<attribute name="ToName">java:/testDatasource</attribute>
</mbean>
The problem was jboss add the prefix java:/ for all data source declared. So finally i had a datasource named testDatasource, overrided with that directive to jdbc/Example DataSource
Hope it works

Categories