How to use runnable jar in another class? - java

I have a runnable java jar file that I need somehow to run (pass params, fetch output) from another java class I'm working on. How do I do that? Do I import it as a package somehow, call it on runtime? Can I invoke "main" method from it or do I just run it with "exec"? Thanks for your answers.

Simply add it to your CLASSPATH and call either the main() method or any other public method which it provides (and which is documented). There is no difference between "normal" and "runnable" jar files, besides an entry in the manifest.
One subtle detail you might need to consider is that runnable jar files are usually self-contained - that is, they contain all required classes, including classes from third party libraries. If you are using the same third party libraries in your project, make sure that there are no conflicts, e.g. by removing the separate third party jar files from your project.
See Lesson: Packaging Programs in JAR Files for more information.

Import it in your code if you need something, that you can not achieve from command line exec solution. Note, you can get problems, if you trying to use some methods from jar file itself, and author changes it later.
Consider Bridge pattern, to put some abstraction layer between jar file and your code, If you not sure, that you use public API.
If jar file is library with stable API, you can be more confident, while using it in your project.
Besides, importing jar file and use methods from it is faster, than parsing process output.

u can import it to your project and then call the publicly exposed methods in that jar from within your application.

Related

How to create globally available libraries in Java?

What I mean is, in Java there is a standard set of packages that can be referenced from any program in any context on the computer. So when I want to process raster images I just add import java.awt.image.BufferedImage to the top of my file and I able to use that pre-built class without referencing the actual java.awt.image package files at all during compilation and run time. Where are these globally importable packages kept and/or how can I make my package files globally available in the same way?
I have been writing a lot of small helper programs lately, most of which do very similar things, and it would be convenient for me to be able to reuse code without explicitly referencing my package files.
Thanks for any help.
you CAN place any jar library you want into your JRE to achieve same result - classes from this jar will be available in classpath at runtime though it is not recommended to do so without a reason :) But if you are just learning and do not want bother with build tools it's OK
[java-home]/lib/ext - standart place for your libraries
[java-home]/lib/endorsed - place for the libraries which API's overwrite default JRE's ones

Using External library in java

I am using a Java external library, a .JAR file that contains a number of classes.
I Have two questions:
I have a problem when using classes in the .JAR file. The problem is when some variables is defined in the class itself, how can I access it? Does the class in the .JAR itself finds it automatically or I should call it?
I would like to know which is best to do: using an external library .JAR file or creating the classes and methods included in the .JAR file and include them in the project I am working on assuming that I have both the source code .JAVA files and the .JAR file of the classes I need to use?
Consider the code below, it is from an external project that I want to use in a current project, I have both .JAR and .JAVA files.
For example the code below has a variable named original_executer that is defined outside this method. If I call this method and give it the required string, will it do its function properly or an error will rise?
public boolean readSet(String setName){
testSet = testSetName;
OriginalLoader myLoader = new OriginalLoader();
original_executer = myLoader.loadTestClass(testSet);
original_obj = original_executer.newInstance();
if(original_obj==null){
System.out.println(" Can't instantiate original object");
return false;
}
return true
}
If you add the .jar to your classpath, you can use everything as if it was defined in your project.
If your .jar file is a external library it is best to keep the library in the .jar and use it from there. Whenever the library gets updated, you can just overwrite the libraries .jar.
given your jar is properly added in the classpath and you have used the necessary imports in your code you can use any class or variables with correct modifier of the jar...
best is to use the external library as jar..and to consume it through package dependency tool like Maven which will automatically download the latest version of jar for you. And then you can compile and run against the latest version
To access the variables defined in the class, you would need to use the getter methods that are supplied. Otherwise, you would need to employ Reflection to grab the values by doing something like
Class.getClass().getField("field_name").set(Class.getClass(), "value");
Although I'm not 100% sure on the validity of that, I'm sure it is something along those lines.
For the second question, I'm not quite sure what you're asking but you should always just add the .jar file to the classpath or if you want to modify the library, download the source code of it and put it into your workspace.

How to monkeypatch a .class file in a jar

I have a jar file that cannot be modified, but I want to use a different .class file in place of one of the members of the jar. How can I tell Java to use the external .class file when the code within the jar attempts to load it?
You could compile another jar file with replacement classes with exactly the same name and put it ahead of the jar file in the class path. For example, this is what the various slf4j bridge jars do to replace calls to log4j or Jakarta Commons Logging in library code with cognate slf4j code; one need not maintain two sets of logging systems and configurations that way.
If you want to override a java... class, you can use some of the command line options to change the boot class path. Look at the -Xbootclasspath options in http://docs.oracle.com/javase/7/docs/technotes/tools/windows/java.html. Heed the warnings.
There is also the lib/endorsed directory if you need to upgrade a third-party jar that Sun uses. Oracle uses other organizations' XML and CORBA libraries; if they release a new version and you need to adopt it, you can.
You can use AspectJ to instrument the code and possibly replace it. An around advice can call the original code if it wants.
You could see if you really need to replace the original code. Some systems provide customization hooks.
You need to make sure the external .class file is loaded first. If a class is already loaded by the class loader then it will not be reloaded. If you are using an application server, then there are ways to configure the preferences for loading classes for class loader. But if you are using a standalone application then you may need to extend the class loader to load the files in the order you want to.

Public class outside a jar file containing multiple packages

So, I have a Java project containing several packages (like com.myapp.a , com.myapp.b, com.myapp.c) for better readability and I want to build a jar to use as a library in another project.
But I just want to expose only some classes and interfaces from this jar. The problem is that if I don't declare these classes public then they can't be seen inside the jar file between the packages (for example I have a class A in com.myapp.a package that is used in com.myapp.b package).
So how can I expose just what I want outside of the jar when I have multiple packages defined inside?
Currently Java does not address this problem directly.
OSGi adresses this problem by explicitly defining the exported package list.
Also hopefully this will be addressed with the Java 8 Modularity system as well.
So one option is to use OSGi, but this option does not work if the jar file is used directly rather than as an OSGi bundle.
Another option is to use code obfuscation (like Proguard), to obfuscate the packages you do not want to expose.
Eclipse "solved" this problem by making all classes available, but classes that were not intended to be used by clients were placed in packages whose name contains "internal". For example, that might mean that you have packages named "com.myapp.b" and "com.myapp.internal.b". It's made clear to users of the classes that internal classes are not guaranteed to be upwardly compatible or even present in later releases.

Third party lib to create jar files?

I've Goog'd but I can't find any third party library that will let you create a jar file programmatically. I amazed that even Apache commons-io doesn't seem to have such functionality.
I'd rather not implement it myself as the API is rather low level. Are there any 3rd party libraries out there that will do the job?
Edit: I meant programmatically in Java. I don't want to drop out to the shell and I don't want to work with java.io.*.
I'm not sure what you mean by "creating a jar file" but ant has a jar task which will create a jar file for you
http://download.oracle.com/javase/1.4.2/docs/tooldocs/windows/jar.html
You don't need a third party library. It's all built into Java (the jar command just uses those classes)
http://download.oracle.com/javase/6/docs/api/java/util/jar/package-summary.html
Edit:
It will require you to still work with java.io.* as that is the only way to create files...
I'd suggest you look at JBOSS Arquillian. It provides a fluent interface to create jar, war, ear etc. See sample below
Archives.create("test.jar", JavaArchive.class)
.addClasses(
GreetingManager.class,
GreetingManagerBean.class);

Categories