Starting java application - java

What is the difference between starting java process by:
java -jar application.war
and
java -classpath application.war org.example.Main
Problem is that I'm starting Spring Boot Application with -jar argument, process starts normally, but in eclipse application starts with exception:
Caused by: java.lang.ClassNotFoundException: com.sun.istack.localization.Localizable

When you launch your app with
java -jar application.war
It will read your MANIFEST.MF and pick up your classpath from there, including presumably your missing com.sun.istack.localization.Localizable.
When you specify the classpath as the war, it finds your Main class but does not include the values from the MANIFEST.MF.

Related

Problem with java classpath when executing jar

I am trying to execute a java application, which is packaged as jar archive.
java -cp .\lib\json.jar -jar ".\myarchive.jar"
I get an error saying that the classes inside my json.jar archive cannot be found.
Exception in thread "main" java.lang.NoClassDefFoundError: json/serializers/JsonTypeResolversInstance
Caused by: java.lang.ClassNotFoundException: json.serializers.JsonTypeResolversInstance
at java.net.URLClassLoader.findClass(URLClassLoader.java:387)
at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
... 2 more
The jar file contains the class, so i think this error should not happen. When executing the code using my IDE it runs without errors.
I have tried to fix this in many ways, without success.
Using the -cp and -jar options at the same time does not work. When you use the -jar option, then the -cp option is ignored.
There are two ways to run code in a JAR file in Java.
First way: Use the -cp option and specify the name of the class that contains the main method on the command line. For example:
java -cp .\lib\json.jar;.\myarchive.jar com.mypackage.MyMainClass
When you do it like this, you specify the classpath on the command line (using -cp). The classpath must contain all JAR files and/or directories that contain all the classes that the application needs. You must also specify the name of the class to run on the command line.
Also, when you do it like this, the manifest file that might be present in the JAR file is ignored.
Second way: Use the -jar option. For example:
java -jar .\myarchive.jar
When you do it like this, then Java will look at the manifest file in the JAR file. The classpath and the name of the class to run will be taken from the manifest file, and the -cp option on the command line will be ignored.
For details see the documentation of the java command.

Include a runtime JAR when running a fat JAR

Pretty sure this is a duplicate question, but couldn't find the answer I'm looking for.
I'm trying to run WireMock standalone with WebHook extensions. Both come packaged as JAR files. First one, wiremock-jre8-standalone-2.28.1.jar is a runnable fat jar and it works like a charm when I type:
java -jar wiremock-jre8-standalone-2.28.1.jar
WebHook extensions (wiremock-webhooks-extension-1.0.0.jar) is a normal JAR that contains a class org.wiremock.webhooks.Webhooks. I'm trying to run WireMock this way:
java -cp wiremock-webhooks-extension-1.0.0.jar \
-jar wiremock-jre8-standalone-2.28.1.jar --extensions org.wiremock.webhooks.Webhooks
And I get the following error:
Exception in thread "main" java.lang.ClassNotFoundException: org.wiremock.webhooks.Webhooks
What I get from this question is that if -jar is specified on the command line, -cp is ignored and MANIFEST is used instead. So I've tried
java -cp wiremock-webhooks-extension-1.0.0.jar:wiremock-jre8-standalone-2.28.1.jar \
com.github.tomakehurst.wiremock.standalone.WireMockServerRunner \
--extensions org.wiremock.webhooks.Webhooks
but got:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/http/client/HttpClient
Of course, HttpClient is part of WireMock dependencies.
WireMock standalone JAR manifest is as follows:
Manifest-Version: 1.0
Main-Class: com.github.tomakehurst.wiremock.standalone.WireMockServerR
unner
I want to run the fat JAR, adding an external JAR to the classpath, but with no original dependencies ignored. How can I achieve this?

Running an exploded spring-boot jar from command line

I'm looking to run an exploded spring-boot jar.
Currently I'm doing
jar xf app.jar
java -cp /lib/*:/ com/domain/module/Main
which seems to begin the app startup, but invariably stops on
[restartedMain] INFO c.a.a.spring.MetricsJersey2Config - Registering InstrumentedResourceMethodApplicationListener for jersey2 with MetricRegistry: com.codahale.metrics.MetricRegistry#43fee23e
The next line I'd usually expect to see is
[restartedMain] INFO o.s.s.c.ThreadPoolTaskExecutor - Initializing ExecutorService
Running the app using
java -jar app.jar
works fine, but for reasons I need to run it exploded.
Is there anything I'm missing in trying to run a spring-boot app this way?
I solved this by running:
java -cp /lib/*:/ com.domain.module.Main
Rather than:
java -cp /lib/*:/ com/domain/module/Main
i'm facing this problem too ! don't forget to copy your clashpath of your .class in main package and spring boot org.springframework package, for example :-cp ./com/*:./org/*

Running Rake Tasks In WAS without JRuby

Related to : Executing rake tasks on an exploded war on tomcat without jruby being installed
I'm trying to run rake tasks in my Tomcat server that doesn't have JRuby installed. I'm using warbler to create a war file.
Using the answer to the linked question, I ran:
java -cp lib/jruby-core*.jar:lib/jruby-stdlib*.jar org.jruby.Main -S rake -T
This gets me the error:
Exception in thread "main" java.lang.NoClassDefFoundError: org/jruby/Main
Caused by: java.lang.ClassNotFoundException: org.jruby.Main
at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
ls lib gets me:
ems-gems-activerecord-jdbc-adapter-1.2.2-lib-arjdbc-jdbc-adapter_java.jar
gems-gems-jdbc-sqlite3-3.7.2-lib-sqlite-jdbc-3.7.2.jar
gems-gems-jruby-jars-1.6.8-lib-jruby-core-1.6.8.jar
gems-gems-jruby-jars-1.6.8-lib-jruby-stdlib-1.6.8.jar
gems-gems-jruby-rack-1.1.10-lib-jruby-rack-1.1.10.jar
gems-gems-json-1.7.5-java-lib-json-ext-generator.jar
gems-gems-json-1.7.5-java-lib-json-ext-parser.jar
gems-gems-therubyrhino_jar-1.7.4-jar-rhino-1.7R4.jar
gems-gems-warbler-1.3.6-lib-warbler_jar.jar
jruby-core-1.6.8.jar
jruby-rack-1.1.10.jar
jruby-stdlib-1.6.8.jar
ojdbc6.jar
Opening up the jruby-core-1.6.8.jar file, I can see that there is indeed a org/jruby/Main.class file.
As one can see from the file listing, there is no jruby-complete jar file, so I can't run the command from https://stackoverflow.com/a/9982556/684934
What am I doing wrong, and is there by now a better way to do this?
I was working on a similar problem 2 months ago, so things may have changed, but I needed to include all the jars in my class path, had to use bin stubs, and had to set GEM_HOME to get everything working. It may have been simpler, but the posts you referenced didn't work for me either.
I actually had jruby installed, (but I was only using it to build the concatenated class path), so my setup was something like:
cd /path/to/application/
export GEM_HOME=/path/to/application/gems
export CLASSPATH=$(jruby -e 'puts Dir["lib/*.jar"].join(":")')
RAILS_ENV=production java -cp $CLASSPATH org.jruby.Main bin/rake -T
Also useful, the jruby-jars gem can be included in your gemfile to set the version of jruby that warbler includes (I was using gem 'jruby-jars', '1.7.0.preview2' as 1.7.0 wasn't released yet)

CLASSPATH issue while accessing Mysql on Linux

I have Mysql installed on my Linux box and wrote a sample program to access one of it's table.
I am using 'mysql-connector-java-5.1.10.jar'
The code is working fine if i put the jar in 'jre/lib/ext'. However, other ways of recognizing that jar are not working. I tried with setting $CLASSPATH and tried to use '.' current directory.
It's failing with the following error :
java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306
at java.sql.DriverManager.getConnection(DriverManager.java:602)
at java.sql.DriverManager.getConnection(DriverManager.java:185)
I usually don't use the global $CLASSPATH variable, the easiest way to get it running is
java -cp .;/path/to/mysql-connector-java-5.1.10.jar[;<other libs>] pkg.name.MyApplication
Sidenote
If you have your application exportet to a jar with a Main-Class attribute ("executable jar") and start it with java -jar myjar.jar, then you have to add all required libraries to the jars manifest, $CLASSPATH and -cp are ignored in this case. And that's why I usually don't use the -jar option...
Edit
To answer your additional question: If the current directory was added to the classpath by default, then the location from where the application was started could influence the application itself.
Imagine an application inside a jar and a start command
java -cp application.jar com.example.Main
Now we have a defined environment: only the content of application.jar (and the jre classes) are on the classpath and part of the application. If the current directory was added to the classpath automatically then all files at the current location (and at locations of all subfolders) would be on the classpath too, intend or not. With a result, that the application might work if started from the users home directory but maybe not if started from the root directory (/).

Categories