Getting information through Servlet from running Java Thread - java

I have a little problem figuring this out the right way.
I have a Java application reading a log file continuously using threads. While that application is still reading the log file, a client should be able to query the current status (i.e. a certain key was found in the log file) through a java servlet.
My current issue is that I am having problems getting that status using the doGet-Method of the servlet. WHile running the thread is supposed to change a single boolean variable.
My question is:
How do I get the Log Reader Thread to start running when I deploy the Servlet on my Tomcat. In idle mode the Log Reader is listening for new files in a folder and starts to read them once they appear?

Please check below link you can use SevletcontexListener
In SevletcontexListener you can start you logger
Link
public void contextInitialized(ServletContextEvent servletContextEvent)
{
System.out.println("ServletContextListener started");
//start thread here
}
public void contextDestroyed(ServletContextEvent servletContextEvent) {
//stop thread here
}

My current issue is that I am having problems getting that status using the doGet-Method of the servlet. WHile running the thread is supposed to change a single boolean variable.
That's probably because of concurrent update of non thread-safe boolean value. For more details on this topic you can read following tutorial on Java Concurrency
How do I get the Log Reader Thread to start running when I deploy the Servlet on my Tomcat. In idle mode the Log Reader is listening for new files in a folder and starts to read them once they appear?
Please refer to following answer, where it is described how to start threads from ServletContextListener using Executors, which are high-level abstractions over threads.
Hope this helps...

Related

Apache Storm - LocalCluster stopped logging but java process still running

We are running a LocalCluster of Apache Storm as a java process i.e via nohup.
We are running a simple Topology with following configuration.
Config config = new Config();
config.setMessageTimeoutSecs(120);
config.setNumWorkers(1);
config.setDebug(false);
config.setMaxSpoutPending(1);
We are submitting the Topology to LocalCluster. Our shutdown hook is the default one found across sources.
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
cluster.killTopology(TOPOLOGY_NAME);
cluster.shutdown();
}
});
Lately we were facing Java Heap issues which might have been solved by increasing Xms, Xmx and using MarkSweepGC.
However, we are running into new problem. The spout logs are not being written to after sometime. There will be no trace of any storm relate Exception/Error.
The main problem is the java process i.e. via nohup is still showing up in ps -ef. What issue would be happening?
You can try enabling debug logging with config.setDebug(true);, which might let you tell what is happening.
Also next time your topology hangs, you should be able to tell what it's doing by either using jstack or sending the Java process a SIGQUIT (kill -3). This will cause the process to dump stack traces for each thread in the JVM, which should let you figure out why it's hanging.
As an aside in case you're doing it, please don't use LocalCluster in production. It's intended for testing.

Error on executing exe from java

`I have written a below code for running exe that presently is ran through windows service. I want to call it by java program. But i am getting below error in image. I dont know how to go through installutil or debug this error. Please help me on this.
`
import java.io.*;
public class exec {
public static void main(String[] args)throws Exception {
try {
String cmd = "D://OGLWindowsService//OGL_21052014//OGL_25_Feb_2015//OGLService.exe";
Runtime run = Runtime.getRuntime();
Process pr = run.exec(cmd);
}
catch(Exception ex) {
System.out.println(ex.getMessage());
}
}
}
You actually have the answer for your question in your first screen. windows tells you that this program is designed to be the Service and could not run from the command line. It also suggests that you use insyalutil to set your program as a service and then Windows will run it when it will need it.
Ususally service runs for some events. Most common - user connects to particular port associated with this service (for example port 80) and when such request occurs then Windows starts service progarm (IIS to answer http call) and delegate this request to this new program. Or delegeates it immediately if program is already running.
So, as you can see, Windows is in charge of the service programs. You cannot start them from command line of from another process (that's your example). You can start/stop/restart process manually in the service control window but that's still not command line or your process.

How to start and stop Tomcat cleanly from Java and why my way doesn't work repeatably?

I am writing a Quartz application that runs on Windows and calls Lucene and Solr to run indexing jobs. It runs a sequence of jobs, and each job consists of these steps:
Make sure Tomcat is stopped (Solr running under Tomcat prevents index dir from being deleted or copied)
Delete old index directory if necessary
Start Tomcat
Make sure Tomcat and Solr app are running
Run the indexing job
Stop Tomcat
Make sure Tomcat is stopped
Copy index directory to an archive
I decided to have the code that starts and stops Tomcat set the system properties that are set in Startup.bat, Shutdown.bat and Catalina.bat, and just call Bootstrap.main with "start" and "stop" parameters. This worked for one iteration, but not when I tried a Quartz run in which I set up two iterations.
When my code shut down Tomcat at the end of the first iteration, all of the usual messages were displayed, including
INFO: Stopping ProtocolHandler ["http-bio-5918"]
(I am using port 5918) but when it tried to start Tomcat at the beginning of the second iteration, it got thes errors:
SEVERE: Failed to initialize end point associated with ProtocolHandler ["http-bio-5918"]
java.net.BindException: Address already in use: JVM_Bind <null>:5918
and
SEVERE: Failed to initialize connector [Connector[HTTP/1.1-5918]]
org.apache.catalina.LifecycleException: Failed to initialize component [Connector[HTTP/1.1-5918]]
I ran netstat -an in a command prompt window, and it confirmed that port 5918 was in use. There's nothing special about the code I am using to check if Tomcat is running. I've seen in various places on the internet.
public boolean isTomcatRunning(String url) {
boolean isRunning = false;
try {
new URL(url).openConnection().connect();
isRunning = true;
} catch (IOException e) {
isRunning = false;
}
return isRunning;
}
but it apparently tells me that Tomcat is not running when it is.
As I said, I am starting and stopping Tomcat by calling Bootstrap.main(new String[]{"start"}) and Bootstrap.main(new String[]{"stop"}). The only thing peculiar about that is that is that when I simply call Bootstrap.main(new String[]{"start"}), it doesn't seem to return (I haven't waited long enough yet to see if it is hanging or just taking a long time), so I have been running it inside a thread.
Maybe that is causing the problem, as it looks like Catalina.bat isn't doing anything special and it returns from startup just fine. I wonder if there is an additional setup I need to do to enable it to run startup in the main thread without hanging.
In any case, this is what I am puzzled about with starting and stopping Tomcat from within my Quartz application, and I would appreciate any help and suggestions you can offer.
I strongly suggest that you wrap your Tomcat instance with a wrapper that controls the lifecycle of your Tomcat instance. Such wrapper is the Java Service Wrapper. An older version (3.2.3 I believe) is "free" and works fine with newer Tomcat instances.
Your controlling application then "talks" to the wrapper to start/stop the Tomcat application. There are multiple benefits with this approach. One of them is that you are not subject to your Tomcat application hanging and the port you are testing not replying anymore.

Runtime.getRuntime().exec(cmd) with JSPs

I have a class with a method that works just find when I run it from the command line. Nothing seems to happen when I call it in a JSP file though. Could I be missing something here? Are there some configuration changes I need to make to have this code working.
public static void toText(String pdfFile, String textFile) {
try {
String[] cmd = {"pdftotext", pdfFile, "/tmp/text1984.txt"};
Process p = Runtime.getRuntime().exec(cmd);
p.waitFor();
} catch (Exception e) {
System.out.print(e.getMessage());
}
}
Regards,
Phiri
This can have 2 causes:
Your webbrowser doesn't run at the same machine as webserver while you're expecting that Java from webserver also runs in webbrowser (which is ultimately untrue).
The servletcontainer where the JSP runs simply failed to execute the command, which can have a lot of causes, such as insufficient permissions or the command just error'ed.
Cause #1 is to be solved by running the Java code in webbrowser instead. This can be done with help of a signed(!) applet. As to cause #2, to nail down its root cause, read this article to learn how to understand and debug "Runtime.exec() does nothing" problems. Read all the 4 pages.
I think most probably it's a matter of the security settings of the server where the JSP files, probably the server (doesn't allow exec calls). So you will have to tune the security settings of the server to allow the call.
Be aware that this may be a security risk.

Illegal access: this web application instance has been stopped already

I have a class which has an init-method defined in xml
<bean id="appStarter" class="com.myapp.myClass" init-method="init" destroy-method="destroy"/>
myClass:
public class myClass{
private Thread t;
public void init() {
t = new Thread() {
#Override
public void run() {
while (true)
try {
doStuff();
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
};
t.start();
}
public void destroy() {
t.interrupt();
}
}
When the app starts, these threads run fine, and everything works just fine
and after sometime i get the following exception.
INFO: Illegal access: this web application instance has been stopped already. Could not load com.sun.mail.imap.IMAPStore. The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.
java.lang.IllegalStateException
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1273)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233)
at javax.mail.Session.getService(Session.java:755)
at javax.mail.Session.getStore(Session.java:569)
at javax.mail.Session.getStore(Session.java:531)
at javax.mail.Session.getStore(Session.java:510)
in the doStuff method:
public void doStuff(){
Session sessioned = Session.getDefaultInstance(System.getProperties(),
null);
Store store = sessioned.getStore("imap");
store.connect(hostName, userName, password);
.
.
.
}
I don't know why, any ideas ?
Problem solved after restarting the tomcat and apache, the tomcat was caching older version of the app.
In short: this happens likely when you are hot-deploying webapps.
For instance, your ide+development server hot-deploys a war again. Threads, that have been created previously are still running. But meanwhile their classloader/context is invalid and faces the IllegalAccessException / IllegalStateException becouse its orgininating webapp (the former runtime-environment) has been redeployed.
So, as states here, a restart does not permanently resolve this issue. Instead, it is better to find/implement a managed Thread Pool, s.th. like this to handle the termination of threads appropriately. In JavaEE you will use these ManagedThreadExeuctorServices. A similar opinion and reference here.
Examples for this are the EvictorThread of Apache Commons Pool, that "cleans" pooled instances according to the pool's configuration (max idle etc.).
I suspect that this occurs after an attempt to undeploy your app. Do you ever kill off that thread that you've initialised during the init() process ? I would do this in the corresponding destroy() method.
Restarting Your Server Can Resolve this problem.
I was getting the same error while Using Dynamic Jasper Reporting , When i deploy my Application for first use to Create Reports, the Report creation works fine, But Once I Do Hot Deployment of some code changes To the Server, I was getting This Error.
If it's a local development tomcat launched from IDE, then restarting this IDE and rebuild project also helps.
Update:
You could also try to find if there is any running tomcat process in the background and kill it.
I had this exact error. My app ran fine inside of the eclipse development environment but when deployed to the production Tomcat server, the app would load fine, then when an endpoint was called, it generated the error:
[Abandoned connection cleanup thread] org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading Illegal access: this web application instance has been stopped already. Could not load []
The error was caused because there were two different java versions. My development environment in eclipse was set to jdk-15 and the production server was running version 11.
To fix the issue, in eclipse, even when using jdk-15, I emulated java-11:

Categories

Resources