-
1. Re: JNDI NameNotFoundException from background thread
jaikiran Jun 22, 2012 10:42 PM (in response to kdolan1)1 of 1 people found this helpfulThe java:comp namespace belongs to a EE "component". The thread that gets triggered and looks up under the java:comp namespace is not an EE component. So you can't access that namespace there. You might want to either use a EE component in that thread which then does the java:comp lookup (assuming you have setup that datasource in the java:comp namespace of that component) or just use the non-component specific JNDI name of that datasource (ex: java:jboss/datasources/...)
-
2. Re: JNDI NameNotFoundException from background thread
kdolan1 Jun 25, 2012 12:28 PM (in response to jaikiran)Thanks. I got something to work.
I tried a number of things and ended up funnelling the call through an EE component (e.g., session EJB).
Using the debugger, I tried changing the JNDI name I was looking up and it worked in some cases (I believe using the jndi-name value in standalone.xml as well as the java:jboss version). However, I opted not to implement the solution this way because:
a) re: jndi-name value in standalone.xml - the whole point of the JNDI name in code and the resolution in deployment descriptors is so the mapping from logical to physical can be changed w/o recompiling
b) re: java:jboss - this does not work if the application is deployed in other EE containers
c) the JNDI lookups encountered by the background thread are in some of our own "common" code that is also used directly by EE components. In the latter case, the lookups succeed.
I also tried using "java:app" and "java:global" and was not successful. I'm not sure if they should work but did not because I needed to add env entry declarations elsewhere (but where?) or if they are also not intended to work outside of EE components.
-
3. Re: JNDI NameNotFoundException from background thread
jaikiran Jun 26, 2012 1:13 AM (in response to kdolan1)1 of 1 people found this helpfulKelly Dolan wrote:
I also tried using "java:app" and "java:global" and was not successful. I'm not sure if they should work but did not because I needed to add env entry declarations elsewhere (but where?) or if they are also not intended to work outside of EE components.
Similar to java:comp, these java:app, java:module and java:global are all EE specific JNDI namespaces. So you can use them from within an EE component. A random thread is not a EE component, so you can't use it there.
Why is that thread looking up that datasource? Instead of letting the EE components, that require the datasource, do the lookup or even injection?
-
4. Re: JNDI NameNotFoundException from background thread
kdolan1 Jun 26, 2012 8:21 AM (in response to jaikiran)Thanks for the extra info.
Why? The application on request of certain commands by a user, does its thing and then some initiates some post-operation function (e.g., log, email). Some post-operation functions are declared as asynchronous (e.g., not needed to be a part of the overall command transaction, if failed could be retried, user gets control back faster). The asynchronous behavior was implemented as a TimerTask, that processes a queue of requests and for each request that is due to be executed, creates a Thread and executes it on that thread. Some of these post-operation functions access the database and the existing code referenced something like "java:comp/env/jdbc/MyDataSource", which was declared in ejb-jar.xml and resolved to the actual JNDI name in jboss.xml (now jboss-ejb3.xml). Lastly, the same code is "shared" w/ code executed in the EJB itself so it works when invoked this way.
Ultimately, the application was written long ago and how the asynchronous behavior was implemented was most likely the choice because it worked and there was probably no other option. The question now rolling around in my head is how does one implement (or what is best practice for implementing) asynchronous behavior today and still have access to the JNDI environment? I'm trying to think of all the background threads we have, if I'm going to encounter additional problems as I try to upgrade and if we need to totally re-work them. Of course (a) and (b) noted in my previous post raised by you are options but not my first choice based on my reasons. Currently, I resolved my issue by creating a new API on my EJB and having the background thread call it. However, it seems awkward because I have EJB A that creates a background thread that calls EJB A which means in my deployment descriptor, I declare EJB A w/ a reference to itself.
In any case, I also recently ran into some information about an asynchronous EJB. I have not had time to dig into this but is this an option and therefore worth pursuing? Finally, we also have Quartz integrated into the application (recent addition). I'm wondering if this is an option since it seems to perform tasks in the background and allow scheduling and retries (a feature of our post-operation functions).
Thoughts?
-
5. Re: JNDI NameNotFoundException from background thread
jaikiran Jun 26, 2012 9:13 AM (in response to kdolan1)Kelly Dolan wrote:
Currently, I resolved my issue by creating a new API on my EJB and having the background thread call it. However, it seems awkward because I have EJB A that creates a background thread that calls EJB A
That's where the problem starts. The EJB and EE spec states that the user application code is not expected to start a thread from within the EE components.
Kelly Dolan wrote:
In any case, I also recently ran into some information about an asynchronous EJB. I have not had time to dig into this but is this an option and therefore worth pursuing?
Yes it is. The reason why @Asynchronous was introduced was to solve use cases like these and not have to resort of JMS MDBs for getting the EE functionality in an asynchronous task. So yes, that's a right path to pursue. You can then invoke the EJB method marked as @Asynchronous from within the EJB, using the bean's proxy (a.k.a business object. @see SessionContext.getBusinessObject() method).
Kelly Dolan wrote:
Finally, we also have Quartz integrated into the application (recent addition). I'm wondering if this is an option since it seems to perform tasks in the background and allow scheduling and retries (a feature of our post-operation functions).
Quartz and other similar timer implementations (and even EJB 3.1 timer service feature) have much more than just triggering asynchronous tasks. Like you say, you can "schedule" the tasks at various intervals. However, if you go the Quartz way, you still will end up with this issue of not being able to use the EE JNDI namespaces and other EE functionality directly within that Quartz task. Of course, you can just implement the Quartz task as something that just delegates to the EE component like EJB. It ultimately depends on the application needs.
-
6. Re: JNDI NameNotFoundException from background thread
kdolan1 Jun 26, 2012 10:17 AM (in response to jaikiran)Thanks!