Tomcat - Running external JAR/WAR - java

So I have a little Tomcat web app I am running, with the following structure :
Main Servlet
Class for Job A
Class for Job B
Class for Job C
Tons of classes used for the various jobs executions
The webapp is compiled & deployed via ant. At the moment, I get a nice Project.war with all classes.
Basically, the main servlet works as a dispatcher. Depending of the webrequest received, it launches either Job A, B or C in a new thread.
I want to improve my application so that I can redeploy the class for Job A/B/C without affecting running processes. Here's how I am conceptualizing it :
I deploy the main servlet, used as a dispatcher.
I deploy A.war, B.war, C.war
I run B.war
I redeploy A.war, B.war is still running
I run A.war
B.war is done, its output is sent back via the main servlet.
To be brutally honest, I have no idea on where to start or where to look at. I thought about using a ProcessBuilder and executing the jar/war in command line, but it feels like the most unsafe thing to do.
Any input is appreciated.
Thank you !

I believe you need a modular application where you have multiple plugins (Jobs in your case) which can be loaded or unloaded when you want, and to be used once available. Check this stackoverflow question it can give you a little help.
But for simplicity, in a previous job we needed something acts like OSGI without using OSGI, we built API using serviceLoader and created an interface for our module (in your case job) each jar will have a class which will implement the interface. And once the job is needed you can call for it from the service loader if it exist you can use it, if not throw some error.

Related

Test dependencies of Java web app library

I am coding a java web app.
When I started, every time I needed to use an external package, I would download the jars manually and download all dependencies of each jar manually and place them in the libraries folder (in Netbeans).
As time went on, I started using a dependency manager (Ant).
Now, I would like to use my dependency manager for all of my external libraries.
If, after executing this change I run my application and it successfully deploys (no ClassNotFoundExceptions and no NoClassDefFoundErrors), is it safe to assume that I have not missed anything and that my application will run smoothly as far as the external packages go?
Or, do I need to individually test out each functionality in my web app to confirm that the changes I made to the libraries didn't change how the application runs?
It's actually depends on the code inside these libraries. Only part of classes are loaded at startup, thus you can miss something. Also there might be a possibility that you're loading some classes in runtime manually, i.e. Class.forName(String) and this code has not been triggered at startup. Thus, I would say you can't be 100% sure.
Generally in Java here are 3 build approaches:
Imperative - you're saying "How to assembly your code". The typical example of this is Apache Ant.
Declarative - you're saying "Which code you want to assembly". The typical example of this is Apache Maven
Mixed - which takes benefits of previous systems. This is Gradle.
How it helps!

Running Java jars as windows service

I have an executable jar and I was trying to create a Windows Service using sc.exe. I used the below code for creating service:
sc create "TestService" binPath= "C:\Program Files\Java\jdk1.6.0_03\jre\bin\java.exe -jar C:\abc\MainClass.jar"
The service got created but when I was trying to start the service I got the below error:
Error 1053: The service did not respond to the start or control request in a timely fashion.
Later I tried to use Java Service Wrapper (Community Edition), the service starts for some time but is getting stopped everytime. The wrapper log tells something like:
Advice:
The Wrapper consists of a native component as well as a set of classes
which run within the JVM that it launches. The Java component of the
Wrapper must be initialized promptly after the JVM is launched or the
Wrapper will timeout, as just happened. Most likely the main class
specified in the Wrapper configuration file is not correctly initializing
the Wrapper classes:
com.MainClass
While it is possible to do so manually, the Wrapper ships with helper
classes to make this initialization processes automatic.
Please review the integration section of the Wrapper's documentation
for the various methods which can be employed to launch an application
within the Wrapper
Could anyone please tell me how can I run jar as a Windows Service without using external software as I can't use any third party app on Client's prod env.
If not what other configs I need to do in Java Service Wrapper to make the service start.
I tried to find some info related to this on stackoverflow but I did not get anything thing. If any one has anything on stackoverflow please feel free to put this in comment.
I have used this approach before in a productive environment, so I can assure you it is safe to use.
The Jar-File is wrapped in an exe and then it is added to the windows service scheduler (or however you want to call this). If you have a maven project this is also really easy to accomplish.
https://dzone.com/articles/installing-a-java-application-as-a-windows-service
Edit: you said you can’t use external software. With this approach everything that is needed is packed in the exe file. Including a JRE, I hope that that is allowed by your client’s policy.

How to make the Activiti workflow in Activiti Explorer call the outer Java program

I installed the Activity Explorer, and H2 standalone server. Everything works fine, as I see: I can start a workflow, claim and complete user tasks, but that's not enough. I need the workflow to call external services, suppose via REST. But I have no idea how to deploy the code to do that.
Is that possible using javascript (or groovy) in the workflow xml, or is there any way to inject Java code, or even deploy Java module?
I am totally confused about the technology, any example could help.
I am sorry for this type of question derived from my lack of experience...
Anyway, I would like to answer it.
One should wright a class implementing JavaDelegate, and pute desirable code inside the execute(..) method, compile, export as jar and put the jar in WEB-INF/lib.
In the .bpmn diagram which is pure xml, Service Task node there should have a reference to that class.
I think there enough key words to have a clue how to search details, so that's all for now.

Tool which runs java MainClasses, design avoiding dependencies trap

I have to implement a Tool which reads a config file and runs application/programs specified in the configuration file. A sort of automated runner for tests. I have implemented a program which does that, however I have hit the dependency wall. In my current design Tool parses the config file and retrieves a Map of ProgramType and list of Jobs. Based on ProgramType, a Runner class is chosen and initialized, runner class is a part of Program src.
//this is just a pseudo code
pkg org.Tool
class Tool {
//after parsing
runJobs(map) {
if(map.get() == ProgramType)
org.Tool.JobStats = org.ProgramType.Runner.run(Job)
}
}
pkg org.ProgramType
class Runner {
org.Tool.JobStats run(Job) {
if(Job = "certain job")
return CertainJob.run(Job)
}
}
To build the Tool I need compiled org.ProgramType.*; to build the ProgramType I need org.Tool.Job and org.Tool.JobStats. The "dependency hell" I have created is obviously very bad design. I came with a solution of simply invoking ProgramType jar and storing the JobStats in a jobStats.txt file and once the jar execution finishes, read the file and process it. This solution is not acceptable as Jobs can be run multiple times with many configurations etc, simply to much *.txt files to handle. I think I saw once a compile solution for my problem, something like "partial-compile" Tool, compile ProgramType, recompile Tool. However I can't find it, also it would be wise to get rid of the "dependency hell" anti-pattern. Thus my question "How I should have designed this".
(I hope that the explanation is clear, if not just ask)
SOLVED
As I wrote in the comment #aviad I was looking for a design pattern, to solve my problem. I found one its called "Dependency Inversion Principle". Here I am linking a pdf document describing the pattern, its worth reading (http://www.objectmentor.com/resources/articles/dip.pdf) (Another good explanation http://java.dzone.com/articles/fun-modules). Thank you all for your help (I really liked the frameworks you have recomended).
I think you still can use most of your code if you can use the SpringBatch framework.
The advantage of using Spring batch is that it is Framework where all the hard job was already done (configuration, multi-threading, persistency etc).
Basically the java programs that you need to run can be executed by running a batch file\shell script that starts:
java -cp %JOB_CLASSPATH% %JOB_MAIN_CLASS_FULLY_QUALIFIED_CLASS_NAME%
So I would use the following design:
The entire solution is Spring -based application.
Controller class (your main class) that reads configuration and runs the show. Controller class populates the job queue with jobs and their configurations. Then every job is retrieved from the queue and Spring batch job is instantiated programmatically and run.
You can also use Commons Exec for executing batch files\shell scripts from java.
Later you can move to run in web container (In order to enable configuration changes and jobs triggering over http) - check Spring Batch Admin
You can also run your solution in sceduled manner if you use Quartz FW
Good luck!

Java framework for hot code deployment and scheduling jar file deployment

Using JAVA framework i want to achieve the following task.
hot code(jar) deployment which will perform certain task in an environment
At any time if i update that jar file it should automatically unload old code and load new code
I want to schedule that deployed jar file to perform tasks.
Currently i see Apache karaf/Felix fulfill this requirement but less help available and difficult to manage.
Any alternate framwork i can use instead of using karaf/felix ?
If you aren't going to go the OSGi route, which you basically implied by forgoing Karaf / Felix (and Karaf uses Equinox, by default) then about the best thing I can suggest for you to consider is LiveRebel when it comes out. #Daniel's answer mentioned JRebel, which is outstanding for hot deployment during development but it is not meant as a tool for production systems. Instead you should check out LiveRebel, also made by Zero Turnaround, might be able to fulfill of your needs. Please note that this is a commercial product but they are offering a private beta right now.
[Edit]
Idiotically, I forgot to mention that there's also Knoplerfish, another OSGI runtime which has a BSD style license. Perhaps give that a shot?
Give JRebel a try. It is a great tool.
Note sure what environment you mean (eg. web, desktop, server-side, etc), but...
Working backwards:
3: Scheduled Tasks
You can achieve this in any Java container with the Quartz Scheduler library. This allows you to schedule events in a CRON like fashion.
1-2: Hot Deployment
Then it's a question of where you want to deploy and how to handle hot deployment. Other answers have mentioned JRebel and OSGI which will work. If you want some super quick deployment (eg. save the code and it's available) and have it hosted in a web container ,then use the Play Framework. It uses Quartz do implement Scheduled Jobs in a very nice way.
For example (from the Play docs) :
#Every("1h")
public class Bootstrap extends Job {
public void doJob() {
List<User> newUsers = User.find("newAccount = true").fetch();
for(User user : newUsers) {
Notifier.sayWelcome(user);
}
}
}
JBoss has the hot deploy feature that your describing. However, I'm guessing it's as complicated to configure Karaf. It may be possible to find out how JBoss is achieving it and use the libraries yourself though.
hot code(jar) deployment which will perform certain task in an
environment
At any time if i update that jar file it should automatically unload
old code and load new code
I want to schedule that deployed jar file to perform tasks.
In a nutshell, hot deploy/redeploy is done like that
Use a classloader (java.net.URLClassLoader is a good start), load the jar(s), actually copy the jar somewhere (temp) before loading it
You need some interface implementation, instantiate the class implementing the interface (META-INF in the jar, custom xml, whatever), configure it (props/xml, whatever)
call start() and perform the tasks.
Monitor the jar: some thread to check it each second and compare the last modified time/size
If changed - call stop() and undeploy, may need to wait for threads, etc, start over
There are a lot of frameworks that allow dynamic deploy
The hotdeploy feature of most web containers (like Tomcat or Jetty) allow you to have the behaviour you want, on web applications.
Such an application can be very simple, and essentially just contain your jar.
What is it you need your application to do?

Categories