Are there JNDI namespace conventions? - java

I have downloaded JBoss EAP 6.1 and I am going to add a new data source. I must bind the data source to a JNDI name. By reading the JNDI name of the sample data source which is:
java:jboss/datasources/ExampleDS
I see that they have used datasources after java:jboss. Is this just a naming convention - that I am not able to find anywhere - or would it be fine using java:jboss/bananaboat/MyDS?`
Is it correct that the first part that is listed below - such as java:comp is the scope and the rest is just normal hierarchy organization?
java:comp/ - The namespace is scoped to the current component (i.e. EJB)
java:module/ - Scoped to the current module
java:app/ - Scoped to the current application
java:global/ - Scoped to the application server
https://docs.jboss.org/author/display/AS71/JNDI+Reference

I had to answer the same question to myself and pulled these links together.
In short, JNDI Naming Policies can be any but JEE defines its own:
JNDI is defined independent of any specific naming and
directory service implementation.
However, one important platform that does define a limited set of
naming policies for using the JNDI is ... JEE.
This would be the most conventional name for the datasource:
The enterprise namespace is rooted in a URL context for the java URL scheme.
For example, a JDBC Salary database might have the name "java:comp/env/jdbc/Salary".
... comp is bound to a subtree reserved for component-related bindings.
... env is bound to a subtree that is reserved for the component's environment-related bindings, as defined by its deployment descriptor.
Resource factory references are placed in subtrees differentiated by their resource manager type.
...jdbc for JDBC DataSource references.
JEE 7 Tutorial also details naming policies to reference EJBs in 32.4.1.1 Portable JNDI Syntax.
Note that #Resource annotation to inject DataSource often specifies JNDI name relative to java:comp/env - see this answer or this answer for portable and deployable solutions.
As mentioned in your updated link, java:jboss namespace is a custom extension provided by WildFly/JBoss only.
To answer the question, the sub-trees under standard namespaces are just normal hierarchy. Obviously, it only makes sense if these sub-trees are (widely) recognized by application server, documentation, processes, etc. Otherwise, I guess nearly flat key-value or random bananaboat/MyDS is fine but still has to be "mounted" under supported namespace like java:jboss.

This is all from memory (I was told by another team member a while ago):
The java: prefix is a JBoss/EE standard. It should be prefixed for all non serializable resources which means they are local to the jvm. After that you can name whatever you like to form the "directory" like structure. e.g. if you use JNDI to get binding "java:jboss/datasources", you will get back a subtree of all resources listed under that name. It will contain ExampleDS and possibly other DataSources as well.
To answer your question: you don't have to name it datasources after java:jboss. But it make sense to name it something meaningful.

Related

What does this lookup addresses mean in Wildfly 8?

I have tested my first sessoin bean using Wildfly 8. I use the following code to obtain a proxy for the bean
InitialContext ctx = new InitialContext();
Object obj = ctx.lookup("java:global/EJBDemo/FirstDemoEJB");
When I print the object out I get the following output
Proxy for remote EJB StatelessEJBLocator{appName='', moduleName='EJBDemo', distinctName='', beanName='FirstDemoEJB', view='interface com.demo.ejb.FirstDemoEJBRemote'}
I can proceed with the RMI with the above lookup and get the desired result.
However, I observed that there are other lookup paths as listed by Wildfly at the time of deployment.
java:global/EJBDemo/FirstDemoEJB!com.demo.ejb.FirstDemoEJBRemote
java:app/EJBDemo/FirstDemoEJB!com.demo.ejb.FirstDemoEJBRemote
java:module/FirstDemoEJB!com.demo.ejb.FirstDemoEJBRemote
java:jboss/exported/EJBDemo/FirstDemoEJB!com.demo.ejb.FirstDemoEJBRemote
When I use the other lookup names names (part before the ! mark), I get the following output
EJBDemo/FirstDemoEJB -- service jboss.naming.context.java.app.TestEJB.EJBDemo.FirstDemoEJB
But I cannot RMI and get the desired result as in the java:global lookup.
My question is what does these other lookup paths listed by Wildfly mean? and can they be used for JNDI lookup as well? If so how to do it?
Before Java EE 6 every application server (Weblogic, JBoss, Glassfish, etc) had their own naming convention for JNDI then the applications weren't portables across servers.
In Java EE 6 the specification has standardized the JNDI address.
From https://docs.oracle.com/cd/E19798-01/821-1841/girgn/index.html :
Three JNDI namespaces are used for portable JNDI lookups: java:global,
java:module, and java:app.
The java:global JNDI namespace is the portable way of finding remote
enterprise beans using JNDI lookups. JNDI addresses are of the
following form:
java:global[/application name]/module name/enterprise bean
name[/interface name] Application name and module name default to the
name of the application and module minus the file extension.
Application names are required only if the application is packaged
within an EAR. The interface name is required only if the enterprise
bean implements more than one business interface.
The java:module namespace is used to look up local enterprise beans
within the same module. JNDI addresses using the java:module namespace
are of the following form:
java:module/enterprise bean name/[interface name] The interface name
is required only if the enterprise bean implements more than one
business interface.
The java:app namespace is used to look up local enterprise beans
packaged within the same application. That is, the enterprise bean is
packaged within an EAR file containing multiple Java EE modules. JNDI
addresses using the java:app namespace are of the following form:
java:app[/module name]/enterprise bean name[/interface name] The
module name is optional. The interface name is required only if the
enterprise bean implements more than one business interface.
For example, if an enterprise bean, MyBean, is packaged within the web
application archive myApp.war, the module name is myApp. The portable
JNDI name is java:module/MyBean An equivalent JNDI name using the
java:global namespace is java:global/myApp/MyBean.

EJB properties file

In my project I have 2 modules, a ejb and a war module. In the war module i have a properties file that is processed when I start the web application (by a listener). For each property in this properties file, i add it to the servlet context.
So, my question is: is it possible to access this properties, in the servlet context, from a enterprise java bean in the ejb module? I want to do something like this, but in a ejb:
ServletContext sc = myservlet.getServletContext();
String xpto = sc.getAttribute("my-attr");
If this is not possible, what is the alternative?
Thanks!
P.S I'm using netbeans and glassfish.
ServletContext is always loaded ahead in the Servlet lifecycle loading. Ref to this link. As you see the Listeners are loaded after the ServletContext is loaded when application starts. You can have your code in the listener class that extends ServletContextListener. Ensure you are extending correct Listener as given in the link.
In your situation, One of the alternative is to have a Singleton class load all the properties from the properties file. for ex: ApplicationPropertiesLoader class can have a Properties map attribute to store the key value pairs of that property file. This class can have a getProperty method that always refer to its internal Properties.
In your servlet class refer to this singleton class to load the properties as required.
Speaking of alternatives, it might be worth a thought to use configuration stored in database, at least if you already have a database connection in your application and have control over the database schema.
We use this technique in all our web applications, mainly for two reasons:
Changes to a property can be done during runtime without monitoring file changes, they can be done by the application itself and one does not need to know a path outside of the deployed application.
Properties can have additional information, such as a type (e.g. number, date, string), a default value, a comment or a user who changed it.
For implementing it, you'll create an application-scoped component which accesses the database properties for the rest of the application.

com.sun.appserv.connectors.internal.api.ConnectorRuntimeException: Invalid resource

I'm trying to figure out where is the definition of the above resources stored. My application does not have and never had such resource defined. So I'm actually sure this is some kind of server reference but the question is where such stuff could be defined. It looks for me like some kind of cached references existing somewhere on the server and used when the same names are tried.
People advice workarounds like creating resources manually or using java:app/ prefix.
However I'd like to go tot the bottom of the problem and resolve the source of the problem instead.
The contain entity manager config could be the first thing to check but where is it?
What config file should I examine, modify or remove.
Here is the beginning of the error message:
Severe: Exception while preparing the app : Invalid resource : jdbc/CustomerDEV1__nontx
com.sun.appserv.connectors.internal.api.ConnectorRuntimeException: Invalid resource : jdbc/CustomerDEV1__nontx
To get rid of it, you´ll need to remove the persistence.xml cached by the IDE. For example (using Netbeans 8 under Windows 8.1):
C:\Users\jMarcel\AppData\Local\NetBeans\Cache\8.0\index\s71\java\14\classes\META-INF\persistence.xml
Hint: in WindowsExplorer, set your directory to C:\Users\yourUser**AppData\Local\NetBeans** and perform a search for the persistence.xml file.
I hope you are not letting the server know what type of resource you are looking up in the JNDI tree and confusing it. You look for JDBC resource in within application. Please note that if you use java:app/ then it means
The java:app namespace is used to look up local enterprise beans packaged within the same application. That is, the enterprise bean is packaged within an EAR file containing multiple Java EE modules. JNDI addresses using the java:app namespace are of the following form:
You have to use java:comp/env/jdbc/CustomerDEV1__nontx for JDBC Datasource. java:comp/env/jdbc denotes it is a JDBC resource in the Java components environment

Difference between javax.servlet.ServletContext and javax.naming.Context

As I knew, Java ServletContext and Context Objects are common used inside Java EE program development. However, I'm not quite sure about what are the differences between them, especially the Context Class usages.
From what I understood, ServletContext is the Object which contains all initializations read from Web.xml so that all servlets in the web application can share those global configurations.
On the other hand, I usually only used Context Object when I needed to dynamically establish database connection with JNDI lookup. Beside that, I'm not clear about other possible usages of this class.
My main concern is does the "context" word of both ServletContext and Context classes represent the same thing or component inside web application?
From the ServletContext javadoc
Defines a set of methods that a servlet uses to communicate with its
servlet container, for example, to get the MIME type of a file,
dispatch requests, or write to a log file.
Basically it's an accessor to the servlet environment. Anything that is relevant to the servlet, you can get it from there. It's really only useful with a Servlet Container.
The JNDI Context javadoc
This interface represents a naming context, which consists of a set of
name-to-object bindings. It contains methods for examining and
updating these bindings.
This is an interface to a resource. You configure a resource with a some identifier which you can retrieve through this interface. You are not limited to using this only in a Servlet Container. For example, you might store a list of connected devices on your network in an LDAP repository. To access this repository, you could write custom code implementing the protocol and interacting with an LDAP server or you could use the LdapContext class, which implements the Context class. Or, you could use it to lookup a JDBC DataSource.
Don't let the fact that they have the same name bother you. They have different goals.
This answer might be of help for when you see Context in a different context.

Possible JNDI lookups within EJB container

I'm going through the EJB 3.1 spec and am trying to grasp the different possible ways a JNDI call can be made.
You can do it using a SessionContext and an InitialContext (or a self-created context based on the Initial- or SessionContext).
Based on which you use the syntax differs, but I can't seem to find the logic behind it.
So my question is: when can I use what syntax to use JNDI calls within an EJB container environment?
The rest of this question just serves as illustration of my point.
For example, I believe this is always possible for a correctly injected sessioncontext or created initialcontext:
ctx.lookup(java:global[/<app-name>]/<module-name>/<bean-name>[!<fully-qualified-interface-name>])
ctx.lookup(java:comp/env ...)
// special ones like these
ctx.lookup("java:comp/UserTransaction");
ctx.lookup("java:comp/ORB");
Sometimes (only for session context?) this shorter version is possible:
ctx.lookup(<bean-name>);
What about in an embedded environment, can only global references be used?
I usually inject EJBs inside EJB container with #EJB annotation. So the JDNI look ups are done by the server at deploy time.
For example JBOSS deployment:
INFO [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-2) JNDI bindings for session bean named TestBean in deployment unit subdeployment "MyEJB.jar" of deployment "MyProject.ear" are as follows:
java:global/MyProject/MyEJB/TestBean!my.project.TestBean
java:app/MyEJB/TestEJB!my.project.TestBean
java:module/TestEJB!my.project.TestBean
java:global/MyProject/MyEJB/TestEJB
java:app/MyEJB/TestBean
java:module/TestBean
Some are per EJB specification some are application server dependent.
If you have to make look ups from context I think the best way is to use java:global.
You can also find some additional info at: http://glassfish.java.net/javaee5/ejb/EJB_FAQ.html#POJOLocalEJB
jndi is a bit like a file system. You can refer to things using a relative path based on where you are in the tree (where you "cd"-ed to).
The injected session context is by default "positioned" on java:comp, so there you reference things that are available in java:comp, without the need to provide the "full path".
Note that java:comp itself is relative to a single EJB bean, or because of historical reasons to the entire Web module.
I'm not 100% sure what you mean with embedded environment, but if the code from which you are doing the JNDI lookup is not part of any of the predefined scopes (like java:module, java:app, etc) only java:global can be portably used.

Categories

Resources