Yano Yano - 1 year ago 75
Java Question

Cygwin terminal error in running .sh file because of a jar file

I am trying to run .jar file for my java code from a .sh shell script file. the jar file name contains "." which is making the Cygwin terminal think it is a directory. Here is the command and the results:

java -jar ./lib/javax.json-1.0.jar


no main manifest attribute, in lib\javax.json-1.0.jar


error: package javax.json does not exist

import javax.json.Json;

With this mark ^ below the period (right after javax).

How can I solve it? I am working on Windows 10. Thanks!


I have written many forms of the .sh file to get it run, but it won't run. The current one is:

# !bin/bash
java -jar ./lib/javax.json-1.0.jar
java -jar ./lib/javax.json-api-1.0.jar
javac ./src/TimeTester.java
java TimeTester

Does this look good?

I am getting the following error:

.\src\TimeTester.java:22: error: package javax.json does not exist

import javax.json.Json; (With this ^ below the '.')


.\src\TimeTester.java:159: error: cannot find symbol

private static JsonObject getJsonFromString(String jsonStr){

And many similar lines in the error.. Any help?


This is my current file:

javac -cp ./lib/javax.json-1.0.jar:./lib/javax.json-api-1.0.jar ./src/TimeTester.java
java -cp ./lib/javax.json-1.0.jar:./lib/javax.json-api-1.0.jar:./src TimeTester

But I am getting:

.\src\TimeTester.java:22: error: package javax.json does not exist

import javax.json.Json;


With With this (^) under the last dot (.Json)


The current .sh file is:

#!/usr/bin/env bash

cd src

javac -cp '../lib/javax.json-1.0.jar;../lib/javax.json-api-1.0.jar' TimeTester.java

java -cp '../lib/javax.json-1.0.jar;../lib/javax.json-api-1.0.jar' TimeTester

The first command (javac) works and generates the .class file. BUT, the second command (java) does not work and it gives the following error:

Error: Could not find or load main class TimeTester

Your help is really appreciated!

Final EDIT:

Thanks for Jim, the shell script now works. Now I got a java execution error:

java.io.FileNotFoundException: .\in_input\in.txt (The system cannot find the path specified)


Answer Source

TL;DR It is a pain to use Cygwin with programs written for Windows because of the conflicting command-line shell conventions between bash and cmd.exe. To compile and run Java programs it is much better to use an IDE such as Eclipse or Netbeans.

However, if you must...

None of this works because you are trying to pass Linux-style paths to the Windows JVM. However you seem to have a more basic misunderstanding:

# !bin/bash  
java -jar ./lib/javax.json-1.0.jar  
java -jar ./lib/javax.json-api-1.0.jar  
javac ./src/TimeTester.java  
java TimeTester  

I am surmising that you think the first two statements make the libraries available to the compiler for the third javac line. This is not true, those two lines attempt to execute the jar file, which of course fails since the jar does not contain a main class

What you should be doing is providing those two library paths as arguments to the -cp option of the javac command.

This is where it gets quite tricky, as you are mixing a Linux-style shell emulator with a Windows JVM. Paths that are intended for the shell must remain in Linux style, while paths that are going to be consumed by the JVM must be converted to Windows format, and path strings for the JVM must be delimited with semicolon (Windows style) instead of colon (Linux style). That introduces a further complication since the semicolon in Cygwin (Linux) is the delimiter for multiple commands on one line, so the path string must be quoted to prevent the semicolon from breaking things.

Also problematic is the naming of the class to be compiled. You have not shown us the package declaration of the Java file, but I'm assuming it's in the default package (i.e. there is no package declaration and it's not package src;). In that case you should be in the src directory, not one directory above.

Finally, once you specify -cp, you must also add the current directory to the classpath on Windows if you want it to be included, otherwise it will not find your newly-compiled .class file.

So the compile and execute commands should be

javac -cp '../lib/javax.json-1.0.jar;../lib/javax.json-api-1.0.jar' TimeTester.java
java -cp '.;../lib/javax.json-1.0.jar;../lib/javax.json-api-1.0.jar' TimeTester

For simple relative paths the Windows JVM will accept forward slashes, but if you have absolute Linux paths (i.e. /cygdrive/c/..., or with the cygdrive path set to /, paths like /c/user/...) the JVM will not understand them and they will need to be translated using cygpath.