Communicating with jar

Hi,
I have a jar file.
To execute the tasks that this jar allows, I need to do :

java -jar myJar.jar -parameter1
java -jar myJar.jar -parameter2

So as u can see I need to put options on the command line.

I want to make a web-app that allows to execute this,
so I can execute these tasks via a web interface instead of commands.

I don't know how to handle the interaction between the web app i'll create and the jar file,
how can I execute the tasks ?

Thank u!
LVL 9
matthew016Asked:
Who is Participating?
 
objectsConnect With a Mentor Commented:
don't need to leave the source, or create an instance. Just call the main method

eg.

ClassContainingMain.main(new String[] { "-parameter" });
0
 
CEHJCommented:
You need to pass the parameters in the request and return the results in the response
0
 
matthew016Author Commented:
HMM, didn't get it, how do I execute the jar ?
0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

 
sciuriwareConnect With a Mentor Commented:
A .jar is executed as you typed it, or by double clicking the file.
In the latter case parameters are not given.

If you want to make a web application, the .jar will probably turn into a .war file
and parameters will not be given that way as there is no commandline.

Use environmental variables for options or control.

;JOOP!
0
 
matthew016Author Commented:
So u mean I should get the source file of the jar and make it a war ?
0
 
sciuriwareCommented:
A web application is not just a standalone application with a different name.
Does the client-server consept ring a bell?

;JOOP!
0
 
enachemcCommented:
The jar is not actualy executed. What is actualy executed is the main class of the jar. The main class of a jar is defined in the META-INF/MANIFEST.MF file:

Main-Class: org.eclipse.core.launcher.Main

This example is taken from Eclipse jar.

What you can do (and should do) is to call the main function from the class described here. You will have to create a Class Loader, add this jar and other needed jars to the class path of this class loader, load the main class by name (using Class.forName()), find the main method, and call it by reflection.

Is this clear enough ?
0
 
CEHJConnect With a Mentor Commented:
You only need to call what the main method calls probably - unless you haven't got the source
0
 
enachemcCommented:
I do not agree with you CEHJ, as the responsible for the jar might change the behaviour or implementation of its library. And there is not advantage in your method. Instead of calling the listed main class, he would have to call another class.
0
 
CEHJCommented:
No - he'd call the main class, but not its main method. The main method is just as likely to change as any other, and in fact any change there would be less likely to be documented, since the main method is effectively client code
0
 
enachemcCommented:
Yes, it is client code, and this why it must be documented. The main client entry in a jar should always be well documented. And you can be sure that the signature of the main method will never change. As for the rest of code, you cannot be sure that is public client code.
0
 
CEHJCommented:
>>Yes, it is client code, and this why it must be documented.

I mean it's a client of the class of which it's a member
0
 
matthew016Author Commented:
sorry, not about the class loader ...
never done this before
0
 
CEHJCommented:
How does the program (in the jar) provide its output?
0
 
enachemcCommented:
let's clraify a thing first: is the jar file added to the class path of the web application? If it is, there is no point in using a class loader. If it is not, then this means that you would have to use classes loaded after the application has started. The only way to do this is to use a class loader.
0
 
CEHJCommented:
If it provides its output to stdout, you will have to (unless you can recompile it) have to invoke a new jvm so you can get its stream(s)
0
 
enachemcCommented:
not true

You can use void java.lang.System.setOut(PrintStream out) to direct output to an owned output stream.
0
 
CEHJCommented:
How would you do that for the output of the other application only?
0
 
enachemcCommented:
you do not.
0
 
sciuriwareCommented:
Glad I went for a walk ............................
0
 
matthew016Author Commented:
Hi all,

I have unzip the jar and put the sources in a project,
everything compiles,

I see also the Main class.

I must do class loading now to execute methods on it ?

I'm really lost,

Thx for any help.
0
 
CEHJCommented:
>>I must do class loading now to execute methods on it ?

No. Create an instance of it by using its ctor
0
 
enachemcCommented:
you should not unzip the classes in your project. Just add the jar to the projects's classpath. If the classes are in the classpath when the application starts, you can call classes as if they are part of your project.
0
 
CEHJCommented:
>>you should not unzip the classes in your project.

That's true. Delete them all and leave just the source
0
 
enachemcCommented:
then do just that. It is correct.  Just indentify the needed class and call it.
0
 
CEHJCommented:
If you don't create an instance, there's no possibility of doing anything about the output
0
 
objectsCommented:
> If you don't create an instance, there's no possibility of doing anything about the output

incorrect, creating an instance has nothing to do with it and is unecessary.
0
 
CEHJCommented:
Can you tell us how you send the output for that application alone elsewhere then please?
0
 
objectsCommented:
ROTFL, please read the question :-D
0
 
matthew016Author Commented:
Well I needed anyway the sources because I probably need to modify some stuff later on it.

So to call the tasks of these sources I can do just "ClassContainingMain.main(new String[] { "-parameter" });" ? no class loading ?

But how do I get output of the sources so that I can display them into my web app ?

The input is for now on just System.out.println's ....
(It would be good for me to actually keep the System.out.println's but redirect them in some way into my web app in some kind of Result object?... )
0
 
CEHJCommented:
>>But how do I get output of the sources so that I can display them into my web app ?

Perhaps objects would like to tell you, since he seemed to be so amused by my last observation..?
0
 
enachemcConnect With a Mentor Commented:
use System.setOut function to redirect to a stream of your choice. This redirects all out (not just that of the called class).
0
 
objectsCommented:
> So to call the tasks of these sources I can do just "ClassContainingMain.main(new String[] { "-parameter" });" ?

yep

> no class loading ?

You can use a seperate class loader if need be, but sounds like it isn't necessary.

> It would be good for me to actually keep the System.out.println's but redirect them in some way into my web app in some kind of Result object?

already been suggested how you can do that :)
you can redirect it wherever you want it to go.

A global replace on the source is another option, but redirect should be fine.
0
 
CEHJCommented:
Don't try to redirect streams in the same vm - it will almost certainly cause problems.

If you are able to create a subclass, do so, and nominate the stream to which you want output to be written. You can then pass a stream reference to it from your serlvet
0
 
matthew016Author Commented:
a subclass of what ... ?
0
 
CEHJCommented:
The application you want to run
0
 
enachemcCommented:
CEHJ, there is no point in doing so. If the application is large, it is pointless to subclass the startup class. He would have to replace all System.out and System.err calls to calls to different streams. And, again, if the app is large enough ... this is not quite a solution.
0
 
matthew016Author Commented:
a subclass of a application containing a lot of classes ?
it's meanless to me, sorry ...
0
 
matthew016Author Commented:
Yes but CEHJ is right, if I redirect Syso then I won't be able to use Syso in the classes I develop that will communicate with the jar.
0
 
CEHJCommented:
Well we don't know how large the application is - it could be just a few lines of code. If it is large, create another VM and handle the stream as i mentioned earlier
0
 
enachemcCommented:
if you implement your own output stream, you can also print to the console when a message is printed to your stream. Just keep references to the old System.out and System.err
0
 
objectsCommented:
> Don't try to redirect streams in the same vm - it will almost certainly cause problems.

not necessarily

> If you are able to create a subclass, do so, and nominate the stream to which you want output to be written.

What????

> if I redirect Syso then I won't be able to use Syso in the classes I develop that will communicate with the jar.

You should really be using System.out in a web application.

> If it is large, create another VM and handle the stream as i mentioned earlier

you definitely do not want/need to create another vm. Far too much overload.
Worst case you just replace System.out in the source with a different stream.
0
 
CEHJCommented:
I think you'll find that your sysadmin prefers that an additional vm be allowed to crash rather than the only one
0
 
objectsCommented:
ROTFL, better run all classes in a seperate VM then :-D
Though strange you critisise others suggestions, after making the same suggestion yourself. go figure ;)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.