Short story :
When I run my java application through the Intellij it's all working.
When I run it through the command line I have some issues.
Long story:
First, I have to say that I have a 'lib' folder inside my project with all the Jars I need and I added it as a Library to the project.
When I compile it from the command line I have to specify a '-cp' to the lib folder, otherwise it doesn't load the jars. Even though it looks good, when I run my java application, I get a 'Error: Could not find or load main class awsUpdater' error
My commands :
For compiling -
javac -cp "../../../../lib/*" awsUpdater.java
For executing -
java -cp "../../../../lib/*" awsUpdater
Here's my class (besides the methods)
package AWSUpdater;
import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.S3Object;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class awsUpdater {
public static void main(String[] args) throws IOException {
String bucketName = "bucket";
String key = "ket";
//AmazonS3 s3Client = new AmazonS3Client(new ProfileCredentialsProvider());
AmazonS3 s3Client = new AmazonS3Client(DefaultAWSCredentialsProviderChain.getInstance());
System.out.println("Downloading an object");
S3Object s3object = s3Client.getObject(new GetObjectRequest(
bucketName, key));
//Get new version of android
String newAndroidVersion = getNewAndroidVersion();
//Download current versions.json
String currentJson = displayTextInputStream(s3object.getObjectContent());
//Edit versions.json with new android version
String editedJson = editJsonWithCurrentAndroidVersion(currentJson, newAndroidVersion);
//String editedJson = editJsonDummyCheck(currentJson);
//Create new file to upload to S3
createFileWithNewJson(editedJson);
//Upload new file to S3
updateVersion(bucketName, key, "versions.json");
}
Would appreciate any help with how to compile and execute my program through the command line. thanks !
you need to add package name
java -cp "../../../../lib/*" AWSUpdater.awsUpdater
I notice that the class awsUpdater is under the package AWSUpdater, so you can not use java -cp "../../../../lib/*" awsUpdater directly.
For Example:
I create a project like this:
|-test
|-AWSUpdater
|-awsUpdater.java
Detail of the awsUpdater.java:
public class awsUpdater {
public static void main(String[] args) {
System.out.println("hello");
}
}
then(now I'm in test/AWSUpdater):
javac awsUpdater.java
java awsUpdater
Everything goes well!
If I add the class to the package, like this:
package AWSUpdater;
public class awsUpdater {
public static void main(String[] args) {
System.out.println("hello");
}
}
then(now I'm in test/AWSUpdater):
javac awsUpdater.java
java awsUpdater
here, it will got the error which is same with yours.
Now, you can go to the package's root dir. (here is test), and then:
javac AWSUpdater/awsUpdater.java
java AWSUpdater/awsUpdater
Now, you will get the correct result.
Related
I have few java files. Main.java uses Picture class from Picture.java file. I want to know how to compile and run Main from command line ?
Here is Main.java:
package com.company;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class Main {
static Picture pic = null; // Picture class ???
public static void main(String[] args) {
long t1, t2;
String name = "bears.jpg";
pic = new Picture(name);
t1 = System.nanoTime();
pic.new_img = meanFilter(pic.img);
t2 = System.nanoTime();
pic.writeImage();
calculateTime(t1, t2);
}
and Picture.java:
...
public class Picture {
public BufferedImage img;
public BufferedImage new_img;
...
Assuming both classes are in the same directory use :
javac Picture.java Main.java
This way the dependent class (Picture.java) is compiled first before your Main.java
To run it you will need to specify the entire package structure and run it from the src directory :
java com.company.Main
You need to specify the whole package.
Try running this:
javac com.company.Picture.java com.company.Main.java
It may be a similar to this question : package does not exist error!
but I don't understand how to manage it.
I try to follow this lesson (in French sorry) https://openclassrooms.com/courses/les-tests-unitaires-en-java
and so I have the following tree :
Garage/test/XXXTest.java, Garage/main/impl/XXX.java, Garage/main/inter/XXX.java
In test I have this code (GPSTest.Java)
package test;
import static org.junit.Assert.*;
import org.junit.Test;
import main.impl.GPS;
public class GPSTest
{
#Test
public final void GPSTest() {
GPS gps = new GPS();
double prix = gps.getPrix();
assertTrue("Test prix GPS", prix == 113.5);
}
}
and in main/impl I have this one (GPS.java)
package main.impl;
import main.inter.Option;
public class GPS implements Option
{
public double getPrix()
{
return 113.5;
}
}
and in main/inter I have (Option.java)
package main.inter;
public interface Option
{
public double getPrix();
}
When I try to compile (I'm in Garage)
javac -cp "C:\Program Files (x86)\Java\junit-4.10.jar" test\GPSTest.java
I have this error
test\GPSTest.java:6: error: package main.impl does not exist
import main.impl.GPS;
Do I need to add Garage in the package name ? In the lesson (linked above) it's the same architecture and the same package name... But they use Eclipse, so maybe there are some differences (I use the command line)
EDIT
If I remove the test part it works :
test\TestGPS.java
package test;
/*import static org.junit.Assert.*;
import org.junit.Test;*/
import main.impl.GPS;
public class GPSTest
{
// #Test
public final void GPSTest() {
GPS gps = new GPS();
double prix = gps.getPrix();
//assertTrue("Test prix GPS", prix == 113.5);
System.out.println(prix);
}
}
With the following command doesn't give error... So I suppose the problem is with the classpath, but how can I fix it ?
javac test\GPSTest.java
Do I need to add Garage in the package name
No, but you need to be in the directory Garage when you compile, such that you are at the head of the following directory tree:
main
main/impl
main/impl/GPS.java
main/inter
main/inter/Option.java
test
test/GPSTest.java
The problem was with the clathpass. I had to add the current file to the path with .; before the rest of the path:
javac -cp .;"C:\Program Files (x86)\Java\junit-4.10.jar" test\GPSTest.java
Specifically I want to use the FileUtils.contentEquals(file1, file2) method.
I've downloaded and extracted files to C:\Users\Dov\commons-io-2.4-bin\commons-io-2.4.
I added exactly that pathname to my Netbeans project Librairies folder but of course import org.apache.commons.io.FileUtils; didn't compile.
What will make the program below compile?
import java.io.File;
import java.io.IOException;
import static org.apache.commons.io.FileUtils.contentEquals;
public class CompareFileContents {
public static void main(String[] args) throws IOException {
File file1 = new File("C:\\Users\\Dov\\Docs\\desktop.ini");
File file2 = new File("C:\\Users\\Dov\\Documents\\desktop.ini");
System.out.println("test1.txt and test2.txt are the same: " +
contentEquals(file1, file2));
}
}
Right click on your project
Properties - Library - Compile tab - Add Jar/Folder and select the .jar File
This is my first java program, so please excuse me if its too naive.
I have a 3rd party jar. I want to instantiate a class in the jar and be able to use its methods. Some details about the class in the jar:
Class File: rediff.inecom.catalog.product.CSVAPI
Constructor: CSVAPI()
Method: UpdateCSVAPI(key, csvpath)
Return: String
I have written the following program:
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.io.IOException;
class MyLoaderClass{
public void myLoaderFunction(){
File file = new File("vendorcatalogapi.jar");
try {
URL url = file.toURI().toURL();
URL[] urls = new URL[]{url};
ClassLoader cl = new URLClassLoader(urls);
Class cls = cl.loadClass("rediff.inecom.catalog.product.CSVAPI");
Object cls_object = cls.newInstance();
System.out.println(cls_object);
String output = cls_object.UpdateCSVAPI(12345,"myfile.csv");
System.out.println(output);
System.out.println("try");
}
catch (Exception e) {
System.out.println("catch");
e.printStackTrace();
}
}
public static void main(String args[]){
new MyLoaderClass().myLoaderFunction();
}
}
I am trying to compile it using:
javac -cp vendorcatalogapi.jar temp.java
But I am getting the following error:
temp.java:17: error: cannot find symbol
String output = cls_object.UpdateCSVAPI(12345,"myfile.csv");
^
symbol: method UpdateCSVAPI(int,String)
location: variable cls_object of type Object
1 error
Looks like the object is not correctly initialized. Please can someone help me with the correct way of doing it
If this is your first java program, then loading the class dynamically is probably overkill. Just use it normally and let the default class loader load it:
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.io.IOException;
import rediff.inecom.catalog.product.CSVAPI;
class MyFirstClass{
public void myFunction() {
CSVAPI cvsapi = new CSVAPI();
System.out.println(cvsapi);
String output = cvsapi.UpdateCSVAPI(12345,"myfile.csv");
System.out.println(output);
System.out.println("Success!");
}
public static void main(String args[]){
new MyFirstClass().myFunction();
}
}
Compile (note that the source code file name must match the class name):
javac -cp vendorcatalogapi.jar MyFirstClass.java
Run:
java -cp .:vendorcatalogapi.jar MyFirstClass (on Unix based)
java -cp .;vendorcatalogapi.jar MyFirstClass (on Windows)
You have to let the compiler know that cls_object is an instance of CSVAPI. If you don't, you can only use the object methods (toString, equals, etc.).
To do this, you can do the following:
rediff.inecom.catalog.product.CSVAPI cls_object = (rediff.inecom.catalog.product.CSVAPI) cls.newInstance();
Please, note that you need to have CSVAPI in your classpath!
Object class doesnt know the methods of rediff.inecom.catalog.product.CSVAPI class.
Class cls = cl.loadClass("rediff.inecom.catalog.product.CSVAPI");
Object cls_object = cls.newInstance();
So, explicit casting is required
rediff.inecom.catalog.product.CSVAPI object =
(rediff.inecom.catalog.product.CSVAPI) cls.newInstance();
will do the job.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Execute another jar in a java program
Basically I want to run an external .jar from the one I'm working on now.
I.e. I want to run foo.jar from bar.jar
I've tried using Runtime and Process to execute "java -jar foo.jar", but it opens foo.jar and then it closes immediately. Any tips?
The easiest solution (as Thorn pointed out) would be to have the jar as a build-time dependency and invoke it statically from your code:
ExternalJarMainClass.main(new String[]{"arguments", "to", "main"});
But if that is not possible, you can use a URLClassLoader to load the jar dynamically. If the jar is indeed runnable, then you can read the main class from META-INF/MANIFEST.MF and invoke main via reflection.
This is a different approach from creating a separate process, as the external code will run in the same process as your application. Perhaps this is desirable, perhaps not - that depends on the situation.
Below's a (hastily written and flawed) sample helper class that does just that.
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class JarRunner {
private final Method entryPoint;
public JarRunner(File jarFile) throws
ClassNotFoundException,
IOException,
NoSuchMethodException {
URL jarUrl = jarFile.toURI().toURL();
URLClassLoader loader = URLClassLoader.newInstance(
new URL[]{jarUrl});
URL manifestUrl = loader.findResource("META-INF/MANIFEST.MF");
String manifest = resourceToString(manifestUrl);
Class<?> clazz = loader.loadClass(findMainClassName(manifest));
entryPoint = clazz.getMethod("main", String[].class);
}
public void run(String[] argsToMain) throws
IllegalAccessException,
IllegalArgumentException,
InvocationTargetException {
entryPoint.invoke(null, (Object) argsToMain);
}
private static String resourceToString(URL url) throws IOException {
InputStream contentStream = url.openStream();
try {
BufferedReader r = new BufferedReader(
new InputStreamReader(contentStream));
StringBuilder sb = new StringBuilder();
String line = null;
do {
line = r.readLine();
if (line != null) {
sb.append(line).append('\n');
}
} while (line != null);
return sb.toString();
} finally {
contentStream.close();
}
}
private static String findMainClassName(String manifest) {
Matcher m = MAIN_CLASS_PATTERN.matcher(manifest);
if (m.find()) {
return m.group(1);
}
return null;
}
private static final Pattern MAIN_CLASS_PATTERN =
Pattern.compile("Main-Class: (.+)");
}
Sample usage:
JarRunner jr = new JarRunner(new File("path/to/MyJar.jar"));
jr.run(new String[]{"arg1", "arg2"});
Can you run foo.jar directly? Does it have a manifest with a main method?
I am guessing that you can. So you want to launch the main method inside of a class like foo.Main
Option 1: Include foo.jar in the classpath. If you are using an IDE, then this just means adding foo.jar as a library. Now you are free to import the package (lets call the package foo) and launch your second java program from a single line of Java code:
foo.Main.main(null);
Most likely you would want to do this in a separate thread:
class FooRunner extends Thread {
public void run() {
foo.Main.main(null);
}
}
and then you would launch with this:
FooRunner secondaryApp = new FooRunner();
secondaryApp.start();
Option 2
You can load the classes in the Foo package at runtime using a class loader.
See the Javadocs for java.lang.ClassLoader and this example of a CustomClassLoader
Check java -jar foo.jar runs correctly from command line. Also ensure java is there in the path. It may be better to provide absolute path to java.exe in the arguments.
Please consider using ProcessBuilder instead of Runtime.