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.
Related
I need to provide a config file path to my Java web application that runs in Apache Tomcat 10.1.
The config path must be set outside of the deployment. It's a property of the machine / stage on which the application is deployed. And not an attribute of the application. So it must not be set in the web.xml.
For example /srv/myapp/prod/config.ini or C:\EclipseDeveloperOnWindows\config.ini.
I've thought about multiple options:
Operating system environment variable MYAPPCONFIG, like PATH or JAVA_HOME: Independent of my application and even independent of the Tomcat container. Downside: May become error-prone if I want to run multiple distributions / Tomcats with different configurations as the same system user.
Java system property as a command line option for Tomcat in CATALINA_OPTS, e.g. -DmyApp.config=/some/path.ini
Tomcat context parameter in <CATALINA_BASE>\conf\server.xml. This way, each Tomcat instance (one CATALINA_HOME, multiple CATALINA_BASE) could define a different value for the config path property. (Do I have to include a reference to the server.xml context parameter in the web.xml? And can I look it up from ServletContext?)
Tomcat environment entry in <CATALINA_BASE>\conf\server.xml - what are the differences / pros and cons of Tomcat context parameters vs. Tomcat environment entries? (Can I look it up from ServletContext?)
Something else, that maybe can be looked up using JNDI?
Did I miss some options? And which one is recommended? Which approach do you use for what reason?
Putting the configuration into the Context is probably your best option. Note that Contexts can be defined in various ways, not just in server.xml.
See the Defining a context in the Tomcat 10.1 docs for details.
For our product, the same war file is deployed to the staging environment and the production environment. The differences between the environments are exhaustively described by the two Context descriptors (one for each environment).
I understand enabling JMX in jetty, we can fetch some information about deployed webapps.
Can Jetty also provide enough information to indicate that a given webapp is up and running, or some metrics that can be considered to identify the state of deployed webapps?
Perform a Jetty Server Dump.
https://www.eclipse.org/jetty/documentation/current/jetty-dump-tool.html
This will output the state of all relevant components within Jetty.
This can be accessed via the various "dump" methods on Server (choose the one that you want).
You can trigger this Jetty Server Dump within JMX as well.
Alternatively, you can ask each of the deployed webapps their running state.
Use the org.eclipse.jetty.util.component.LifeCycle interface, and the .isRunning() method.
The LifeCycle interface is available on all deployed webapps, even if they are an instance of WebAppContext (for war files), or ServletContextHandler for manually created webapps, or even ContextHandler for "bare metal" handling of requests.
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
My system is divided to 2 or 3 servers architecture, and only one server has a webApp
Since we use javaMelody to monitor the webApp server, is there a way to use on a regular, no-
webApp JVM, and if so, how can we access the data
I would say include your application into a webapp (a war file for example) then deploy it in a server like Tomcat or Jetty. By the way, Tomcat or Jetty can be embedded.
Otherwise, there is currently no way to do this.
I'm trying to do the following:
Imagine you have a Java EE application running on Tomcat using Spring as the IoC engine.
I have another jar in the application that has full access to all the resources. i.e. I can instantiate the same application context that is running in tomcat but it takes around 30 seconds to instantiate all the dependencies.
Anyone knows if it is feasible to retrieve current tomcats ApplicationContext from the outside?
There is a way to ask for the WebApplicationContext inside a servlet but I'm not on it, I only have a jar with a main method.
No. You have to be running within tomcat (a webapp) to be able to access the servlet context (and from there - the application context). You are not even in the same runtime with the main method.
If you want to get some information from the context, you should expose it as a service. For example:
a restful service, via Spring-MVC
via JMX
via JNDI