How Do I Install a Jar? - java

I was reading some documentation for db2jcc4.jar when something caught my attention in the following (emphasis added):
The following command will retrieve the JCC driver version if executed from the command line:
java com.ibm.db2.jcc.DB2Jcc -version
Or for drivers that are not yet installed:
java -cp ./db2jcc.jar com.ibm.db2.jcc.DB2Jcc -version
All I have is the db2jcc4.jar file - it didn't come with an installer or anything. I can run the second command and it works fine, but the first gives me this stack trace:
Exception in thread "main" java.lang.NoClassDefFoundError: com.ibm.db2.jcc.DB2Jcc
Caused by: java.lang.ClassNotFoundException: com.ibm.db2.jcc.DB2Jcc
at java.net.URLClassLoader.findClass(URLClassLoader.java:434)
at java.lang.ClassLoader.loadClassHelper(ClassLoader.java:665)
at java.lang.ClassLoader.loadClass(ClassLoader.java:644)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:358)
at java.lang.ClassLoader.loadClass(ClassLoader.java:627)
Could not find the main class: com.ibm.db2.jcc.DB2Jcc. Program will exit.
This tells me that the jar is not yet installed. In all the time I've worked with Java, I've never heard of installing a jar. How can I make it so that the first command works instead of having this issue and printing a stack trace? How can I install a jar?
It looks to me like the second command includes a flag, -cp, which modifies the classpath. I'm guessing that means that all I need to do is move my jar file into a specific directory. I tried putting it in /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.33.x86_64/jre/lib but that didn't make it so the second command would work. I'm stumped and would appreciate any suggestions for where exactly I need to move this jar for it to be considered installed.

There is no such thing as "installing" a jar. To be used by a Java application, jars have to be accessible in the classpath. Take a look at this link:
http://docs.oracle.com/javase/tutorial/essential/environment/paths.html

By installing the java jar they meant that the jar is available to your program (physically present and found in your class path). If the Path to the jar was not setup then you have to options:
+ copy the jar file to your existing path
+ include the jar file in the command line
java -cp <path_to>/db2jcc.jar com.ibm.db2.jcc.DB2Jcc -version

It looks to me like the second command includes a flag, -cp, which modifies the classpath. I'm guessing that means that all I need to do is move my jar file into a specific directory.
I would say that you need to explicitly include the jar file itself on the classpath. Personally, I generally do not attempt to "install" a jar as you describe, but rather create some sort of script or executable jar file that will facilitate the establishment of the correct classpath.
EDIT: In the context of deploying code to an application server, then "installing" the jar would make sense--typically there's a shared lib folder available on an application server where you can simply drop the jar and the code will become available to all the applications running on the server--this can become a bit of a management headache, however and I often will prefer to have a completely self-contained deployment over sharing jar files between applications--YMMV, however.

You commented thus:
Your link has this comment - (Classes that are part of the JRE, JDK platform, and extensions should be defined through other means, such as the bootstrap class path or the extensions directory.) - How would I go about adding the jar through that?
That is a bad idea, for (at least) the following reasons:
Putting stuff into the extensions directory is going to potentially affect every Java application that you execute. Not just the application that you are trying to "install". In some cases, this may to lead to unexpected breakages due to conflicting versions, etcetera.
When you update the Java installation, the standard installer, RPM or whatever is going to create a new installation tree. But it won't copy anything from the existing installation. So a Java update is likely to break any application that depends on stuff in "extensions".
If you try to solve the above problems by "embedding" a Java installation, you risk losing track of where your Java installations are. This makes applying Java security patches problematic. And of course, embedded JREs take up a lot of disc space ... at ~100Mb a time.

I suspect that "Installing a JAR" is a poorly chosen terminology that likely means placing the jar on the JVM classpath" - i.e. in order to make it available to an application. The recommended ways of doing so vary depending on the Java platform (whether it is a server platform or a client side platform).
For example, on a Java EE server, you could package the jar file within the application, or define it as a shared library, and attach it to the server's classloader or the application's classloader to make it available to that application. Third party applications, such as various IBM products, will come with their own instructions as to how to 'install' a db2jcc4 driver.

Related

how to run another .jar file when the current program has a bundled jre?

Before when users were required to have a jre installed to run aps:
ProcessBuilder builder = new ProcessBuilder("java -jar execute.jar");
Now with jlink and jpackage being released .jars can be deployed with a bundled jre.
What is the correct method to start another .jar from a program that had been deployed with jlink/jpackage?
java -jar will not work as java is not installed on the end user anymore
see:
How to call an embedded jre from command line in order to run java applications
This is a similar problem but does not address creating the .jar with jlink/jpackage
If you have a main class defined, you should be able to run "java -jar HelloWorld.jar".
Otherwise seems like you can create a launcher pointing to a starting module.
From Redhat Reference:
https://access.redhat.com/documentation/en-us/openjdk/11/html/using_jlink_to_customize_java_runtime_environment/creating-custom-jre-modular
Create a custom JRE with the required modules and a custom application launcher for your application.
$ ./jdk-11/bin/jlink --launcher hello=sample/sample.HelloWorld --module-path sample-module --add-modules sample --output custom-runtime
$ ./custom-runtime/bin/hello
If you have to run the second JAR in its own JVM, then you have to have a JRE or JDK installed to do that.
Alternatively, you need to use jlink or jpackage or whatever to turn it into a self-contained application and distribute that instead of the second JAR. The user has to install that application in a place that your main application can find.
In either case, you run the second application as a separate process; i.e. as a separate JVM.
If it acceptable to run the second JAR in the current JVM, then it may be possible to do the following:
Open the JAR file to read its MANIFEST.
Fetch the Main-Class and Class-Path manifest attributes
Create a new classloader with a classpath that includes the second JAR and all of its dependencies. (This assumes that they are available ... at the locations specified by the Class-Path attribute.)
Use the classloader to load the main class.
Use reflection to find and call the main classes entry point method; i.e. the static void main(String[]) method. Pass it a String[] to represent the command line arguments.
There are a couple of problems with this approach.
The application you are running from the 2nd JAR will share the environment with your main application. The same standard input/output/error. The same current directory and environment variables.
If the second application misbehaves ... it can bring down the main application in various ways. A security sandbox might help, but it won't protect against everything.
If the main application has been distributed with a custom JRE, then it may not include all of the Java SE classes that the second application needs. If that is the case you will get classloader exceptions or errors.
Finally, this approach may not work at all if the packaging technology you use uses an AOT compiler to compile the main application + all classes that it uses to native code.
UPDATE - Now that I understand what you are actually doing here (you have a main app and an updater app), I think there is another way to do this. The jlink utility allows you to create a bundle which has multiple entry points. When this is installed, I would expect it to appear as commands with different names that are links to the same executable. They would (naturally) use the same embedded JRE.
Read the following for more information:
For jlink - Java Platform, Standard Edition Deployment Guide: Self-Contained Application Packaging: Supporting Multiple Entrypoints
For jpackage - Packaging Tool User's Guide: Support Application Requirements: Add Launchers
Note that doing it this way would address possible issues with functionality missing from the bundled JRE. The jlink or jpackage command should make sure that all classes / modules that are needed will be included.

Journey browser Java Chromium Embedded framework throwing error?

I am trying to use a library called Journey browser which uses the Java Chromium Embedded Framework. I first created a Java Maven Project with Netbeans and I edited the pom.xml to match the values on the library's guide, which is here: https://github.com/CodeBrig/Journey, to add the maven dependencies. (No errors detected by Netbeans) I then built the project to download the maven dependency and put their default code (modified slightly) in the main class. Netbeans found no errors in the code. However, when I run the project I get a "no chrome_elf in java.library.path". I think this has something to do with embedding JCEF, but I am not sure how to add this to the "java.library.path" in Netbeans.
How do I fix this "chrome_elf" problem?
Also, if I am able to fix this will it be an error for production if someone doesn't have "chrome_elf" installed?
For Windows
This happens because the chrome_elf.dll (on Windows) file cannot be found.
Java is looking for this file on java.library.path - which (on my machine, anyway) refers to all the locations referenced by the Windows %path% environment variable.
One way to fix this is to download one of the pre-built distributions from that GitHub page (for example the Windows one, referred to here):
https://github.com/CodeBrig/Journey/releases/download/0.4.0-78-assets/jcef-distrib-windows64.zip
Then unzip the resulting jcef-distrib-windows64.zip. In the win64\bin\lib\win64 directory under that main directory you will find the chrome_elf.dll you need - and other binaries which are also needed.
Add this directory to your path - either by adding it to the Windows environment variable or via java -Djava.library.path=....
For example, the path may be similar to this:
C:\your\path\to\jcef-distrib-windows64\win64\bin\lib\win64
This should allow you to run the demo code provided in the JourneyBrowser class. A browser window should open as a result.
Here is the browser:
The above steps worked for me - and the only files I needed to keep from the (large) distribution download were those in the jcef-distrib-windows64\win64\bin\lib\win64 directory. It's possible that I already have some other dependencies which may be needed - so I cannot guarantee this process will also work for you.
For Linux (and MacOS)
I have not tried this on a Linux machine. But in that case, I believe you will need to download and unzip the jcef-distrib-linux64 release - and then point to the jcef-distrib-linux64\linux64\bin\lib\linux64 directory, containing libcef.so and other libraries.
Similarly for MacOS, there is a distribution which can be downloaded and unzipped.
Alternative
An alternative is to simply use the pre-built distributions provided on GitHub, using the commands provided. Obviously, in this case, you will not be creating your own customized implementation (so, no JourneyBrowser class).
copy scr/native/Release to jcef_build/native/Release from the default output directory of VS.check whether the Release exists in java.lib.path

Set CLASSPATH on Mac

Can someone please help me, I'm almost desperate because I can't find solutions for a Mac.
I have written two .java files that I would like to use as a library for all new projects.
For this I found out that I have to set the CLASSPATH.
The java files path:
/Users/thomas/Soft/IN_OUT/In.java
/Users/thomas/Soft/IN_OUT/Out.java
Don't bother with it. The concept of CLASSPATH is misguided in the first place (because you can run more than one java app, ever, on your system, setting the classpath globally is misguided as a concept), and on most platforms, libraries and tools, this isn't the intended way to configure classpaths.
For example, in IDEs, you configure classpaths on a per project basis.
When compiling code or with javac or running code with java, you can supply the classpath with the -classpath option (or shorten it to -cp). For running jar files (java -jar foo.jar, or double clicking a jar), the classpath is taken solely from the Class-Path manifest entry in that jar file; both the -cp and the global CLASSPATH variable are ignored.
I get that you want these files to be available to 'all projects', but that's just not how it works. If you update these files, all your old projects would break, or at least you'd have to consider if they might. You'd also be extending these files to eclipse, intellij, and any other java apps on your system which makes no sense. That's why this notion of 'make these available to everything' isn't a particularly sensible thing to want.

Simple swing application. The jar file runs on my computer, but not others

This is my first question, so apologies for any mistakes. I'll try and give all the info I can. Basically I've written a simple swing application which just loads in image into a JPanel and displays it. I'm using Netbeans 7.1 and I have the latest version of the Java SDK.
Anyway, I've used the "Build" feature in NetBeans 7.1 to deploy my application into a Jar file. When I double click the Jar File on my PC, it runs without a problem. However when I put it on other computers (Tested on 2 others so far, both with the most current JRE) it fails to open, citing the following error:
could not find the main class: swong.Startup. Program will exit
swong is my package name, and Startup is the location of my main method. I have checked the manifest file which is created with Netbeans' build, and it[the manifest] does indeed contain the location of my main method class.
From searching, I've come across similar issues in which the classpath is set wrongly, but I don't understand how this could cause my particular error.
If someone could help me, I would be over the moon. I've been studying java for a year or so, and I've got a good handle down, but I've NEVER been able to make a Jar that runs on a computer which wasn't my own. So, 10 points and thanks in advance.
xo.
EDIT: Thank you for the responses. I'm doing shift work and swamped, but I will test and poke with these responses tomorrow and provide more information. Thanks again. xo
I had d same problem while distributing my app. There is 1 solution that you create a batch file with 'java -jar AppName.jar' and asking user to double click on this batch file to execute your app. What i did was to provide a JRE installation exe(eg: jre_1.7.0) with your app.
Now create a Batch file (install.bat) in which write following commands
jre_1.7.0 -> this will install jre on user's pc
set path="C\Program Files\Java\jre_1.7.0\bin"
java -jar yourAppName.jar
Why i installed JRE because different people have different JRE versions installed. So this makes it difficult to set path to the installed JRE's bin folder & calling the 'java -jar' command. Hence as you know which folders your JRE installation will create hence it is easy to set path and execute your jar file with 'java-jar' command.
Check that your jar file has the following structure (at least)
jarfile.jar
|---------- swong
|---------- Startup.class
|---------- META-INF
|---------- MANIFEST.MF
It seems like the class "Startup" is missing. Maybe your jar only contains the .java files, not the compiled classes.
This error message can be a mistakable java7 error, when you try to start java7 compiled classes with a different Java Runtime Environment then java7. Have you validated, that your .jar is started within a Java7 environment on those other test machines? Sometimes it happens, that you have installed different versions of JREs and you might not be sure which one is actually started.
To check which enviroment is used, you can check in your registry for the following value:
HKEY_CLASSES_ROOT\jarfile\shell\open\command
this should point to your latest JRE. Or if you'd like to stay compatible to java6 as well, define the appropiate compile level in your build environment.

Where do I put Java Dependencies to run crawler4j-2.2.jar?

I'm new to Java and aren't sure where to place the Java Dependencies which are required to run crawler4j. Do I put them in the same folder, or do I put them where Java is located on my machine, or what? Please help me.
Putting the dependent JARs in the same folder as your application JAR / bytecode files is a reasonable approach. As others mention, you need to ensure that the actual folder containing the JARs is on the classpath when the JVM is launched to run the application. The -cp argument is the recommended way to do this, and it is common practice to create a little shell script / batch file to launch the app with the appropriate JVM parameters.
Putting them into the Java installation is not a good idea for a couple of reasons.
It might have unforeseen side-effects on other applications run using that installation. This includes applications run by other users.
It will make upgrading your Java installation to the next patch level more difficult.
You need to put them on the CLASSPATH. If you're running your/the application from the command line you can specify your classpath using the -cp argument for java
You put them in your classpath. The classpath can be specified with the -cp argument when you run the java program.
java -cp depend1.jar;depend2.jar;etc... Class2Run

Categories