Propagate Java EE context Websphere - java

I am working on Jersey based JAX-RS2 app running on Websphere 8.5. I am using async feature to spawn a new thread. The issue is that the new thread is not getting the Java EE context required for jndi lookups. The error that I get is:
A JNDI operation on a java:comp/env name cannot be completed because
the current thread is not associated with a Java Enterprise Edition
application component. This condition can occur when the JNDI client
using the java:comp/env name does not occur on the thread of a server
application request. Make sure that a Java EE application does not run
JNDI operations on java:comp/env names within static code blocks or in
threads created by that application. Such code does not necessarily
run on the thread of a server application request and therefore is not
supported by JNDI operations on java:comp/env names.
There is feature in Java EE 7 for ManagedExecutorService that can be configured in websphere. I am not able to use that as Websphere 8.5 supports Java EE 6 only. I am not able to do the lookups in advance as there are third party jars included that need the Java EE context to work.
I want to propagate Java EE context to the newly spawnned thread. Please suggest if that is possible.

It is possible to submit the task to a new thread having J2EE context by creating a Work Manager in WebSphere Application Server. For WAS 8 and above the WorkManager that is available in the full profile is now also an ExecutorService. The steps for this are:
On WAS admin console goto Resources -->Asynchronous Beans--> Work manager and created a new work manager with jndi name wm/myWM.
In java code do a jndi lookup for the work manager.
ExecutorService execService = (ExecutorService) initialContext.lookup("wm/myWM");
Submit the task to Executor Service.
execService.submit(new AsyncJob(inputData, asyncResponse));
On Websphere Liberty profile, this can be configured as managedExecutorService. Following additions are required in server.xml
<feature>concurrent-1.0</feature>
<managedExecutorService jndiName="wm/myWM">
<contextService>
<jeeMetadataContext/>
<classloaderContext/>
<securityContext/>
</contextService>
</managedExecutorService>
More details are in the pdf at this link: ManagedService WAS 8.5

Related

Issues deploying a Java application to Tomcat

I built a simple Java web application. It provides a series of RESTful APIs for the user to carry out certain operations on a Java DB through a web interface. I used NetBeans environment during the development, and Glassfish for testing.
Now that I finished it, I would like to be able to deploy it on another machine using binaries (although as for now I use the same machine until I learn how to do it).
I installed Tomcat 7, and moved the .war file into Tomcat's webapp folder. The application deploys. Thereafter I try to read some data from the databse using a button I created just for this, but get the following error
I am not sure what went wrong, but I have two theories.
1) The web application cannot connect to the database. Yet when I attempted to run the application again, after starting JavaDB from NetBeans, there was no difference.
2) Somehow, the application cannot reach the Node service. I assumed that there will be no need to change the API links while moving the app, but perhaps I was wrong.
Or maybe there is some other issue I did not consider? I will be grateful for any advice about how to properly deploy such an application.
EDIT: The issue was solved by using TomEE.
The error is come from your application server of choice.
TomCat is only a servlet container (means it only support Servlet/JSP).
Any other feature (JAX-RS, CDI etc) require a Java EE certified server e.g. GlassFish, WildFly,Payara, WebLogic, OpenLiberty or TomEE.
TomEE could be your best bet if you want to use TomCat in your production or test environment, it is basically TomCat + Java EE other feature.
EDIT:
TomEE don't have a GUI for JNDI datasource configuration like GlassFish, you need to edit conf/tomee.xml
<Resource id="myDataSource" type="javax.sql.DataSource">
jdbcDriver = org.apache.derby.jdbc.ClientDriver
jdbcUrl = jdbc:derby://localhost:1527/dbname
userName = app
password = app
</Resource>
And in your java code:
#Path("resources")
#Stateless
public class MyResources{
#Resource(name="myDataSource")
DataSource dataSource;
#GET
public Response SomeMethod(){
//Do stuff here
}
}
You can check here for more detail configuration on data source.

Spring JMX - Purpose of <context:mbean-server>

I am going through 'Chapter 20 - Managing Spring bean with JMX' from the book 'Spring In Action' 4th Edition by Craig Walls. There is one paragraph in this chapter on page 527.
From whence the MBean server?
As configured, MBeanExporter assumes that it’s running in an application server (such as Tomcat) or some other context that provides an MBean server. But if your Spring application will be running standalone or in a container that doesn’t provide an MBean server, you’ll want to configure an MBean server in the Spring context.
In XML configuration, the <context:mbean-server> element can handle that for you. In Java configuration, you’ll need to take a more direct approach and configure a bean of type MBeanServerFactoryBean() (which is what does for you in XML).
I have couple of questions on the above paragraph.
Does it mean that when we are running the application on server like Tomcat, <context:mbean-server> declaration is no longer required?
If above statement is true, who takes care of locating the MBean server when we are running on server like Tomcat or any other application server?
Thanks in advance!
That information is a little out of date...
or some other context that provides an MBean server.
Starting with Java 5 (if I recall correctly), the JVM has a built in MBeanServer. Prior to that, you had to be running in an App server, or provide some other MBeanServer such as mx4j.
Regardless, you still need the server bean declaration; it tells Spring which server to use (the underlying MBeanServerFactoryBean's locateExistingServerIfPossible is set to true by the XML namespace parser. If that flag is false, the factory bean would create an additional MBeanServer.

Accessing Tomcat 8 JNDI from Standalone JVM

I have a legacy webapp recently converted to running on a Tomcat 8 server that calls a java command (Runtime.getRuntime().exec) in the contextInitialized method. This java program then needs to lookup and use the resources (database info) that are set up in the Tomcat context.xml file. It doesn't appear that Tomcat exposes these resources like Websphere.
So what is my best route to access these resources in this separate JVM? Maybe there is a context friendly way to spin off the java process?
Simply put, you can't. The JNDI context is available as read-only from within the webapp.

DI in an EJB/MDB Application

I'm currently developing a small EJB application running on IBM Websphere Application Server 7 (Java EE 5). The app mainly consists of one MDB listening for incoming MQ messages which are transformed and stored in a DB. Currently I'm using a lot of Singleton/Factories to share configurations, mappings, datasource lookups etc. But this actually leads to some very hard to test code. The solution might be using a (simple) DI framework like guice/spring to inject the different instances. The question is: Where to place the initialization/ setup code? Where is the main entry point of the application? How can I inject instances into the MDBs?
it might be worth looking at backing off from using Guice, and trying to work with the injection mechanisms already available with Java EE 5.
Regarding finding a suitable "startup point", unfortunately the EJB specification does not define a way where you can have a bean run at startup. However, the web profile of the EE spec does have one -- you can add a WAR to your application, and set a servlet listener component:
http://java.sun.com/javaee/5/docs/api/javax/servlet/ServletContextListener.html
You can set this to start whenever the application is loaded and started by the container (WebSphere). Watch out for classloader issues though.
Using Spring, you can do it via EJB3 interceptors, see http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/ejb.html#ejb-implementation-ejb3
Useful info on caveats are in the javadoc, make sure you read it: http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/ejb/interceptor/SpringBeanAutowiringInterceptor.html

JMX - MBean automated registration on application deployment

I need some direction with JMX and Java EE.
I am aware (after few weeks of research) that the JMX specification is missing as far as deployment is concerned. There are few vendor specific implementations for what I am looking for but none are cross vendor. I would like to automate the deployment of MBeans and registration with the Server. I need the server to load and register my MBeand when the application is deployed and remove when the application is un-deployed.
I develop with:
NetBean 6.7.1, GlassFish 2.1, Java EE 5, EJB 3
More specific, I need a way to manage timer service runs. My application need to run different archiving agents and batch reporting. I was hoping the JMX will give me remote access to create and manage the timer services and enable the user to create his own schedule. If the JMX is auto registered on application deployment the user can immediately connect and manage the schedule.
On the other hand, how can an EJB connect/access an MBean?
Many thanks in advance.
Gadi.
I investigated JMX and EJB in Glassfish few years ago, so I don't remember all the details. But this might still help.
Glassfish-specific JMX. Glassfish has AMX and custom MBean can be deployed. AFAIK, such beans are meant to monitor the server itself, not to interact closely with a specific application. Such bean can be made persistent, and Glassfish will store their value somewhere across restart. Maybe have a look.
Registration and lookup. You can register MBean anytime from within an application using the MBeanPlatform, or MBeanServer. See this link, I don't remember exactly. You can also lookup other JMX bean and invoke operations on them. The names for the lookup are a bit crazy though. You can register the MBean when the app. starts from within a ServletContextListener.
Classloaders and deployment. The MBeans and the EJB instances are in distinct Classloader. I think you will need to place the .jar with the MBean implementation in the Glassfish deployment directory structure or add it the list of .jar in the classpath via the admin console. You can relatively easily manage to register a bean from within an EJB module, but a bean can not access a EJB easily, at least from my experience.
I managed to use plain JMX to expose statistics from my EJB application, and that worked relatively well. But I don't know if it's adequate to have something more interactive, as in your case where you want to have the EJB change their behavior depending the timer configured with JMX. I fear you will have troubles with this approach.
Hope it helps, despite the vagueness of what I remember.

Categories

Resources