So, I've added a git repo to my project (sjxlsx). I've then right-clicked the repo and imported into the package explorer. I then went to Project->Build path in order to make sure it's on "Required projects on the build path".
When I debug on Eclipse, works just fine.
I'm now trying to export as a running jar and when I execute it outside of Eclipse, it somehow is giving an error (empty.xlsx not found). That is, because in the XLSXWriterSupport, the open method is fetching this empty.xlsx file. On debug, it's working as expected but on converting to a running jar, it's giving me this error.
This is due to this 'empty.xlsx' file being on the resources of the other project. How can I solve this?
https://github.com/davidpelfree/sjxlsx/blob/master/src/main/java/com/incesoft/tools/excel/support/XLSXWriterSupport.java
This is because a resource on the class path is not a File on the file system.
Here it is packed in a jar (zip format).
The wrong code:
if (getClass().getResource("/empty.xlsx") == null) {
throw new IllegalStateException("no empty.xlsx found in classpath");
}
workbook = new SimpleXLSXWorkbook(new File(getClass().getResource("/empty.xlsx").getFile()));
As SimpleXLSXWorkbook has only a File constructor (AFAIK), you need to create a temporary file.
Path tempPath = Files.createTempFile("sjxlsx-", ".xlsx");
Files.copy(getClass().getResourceAsStream("/empty.xlsx"), tempPath);
workbook = new SimpleXLSXWorkbook(tempPath.toFile());
Better have some provision to delete temp files, for instance creating them in a specific directory, see Files.
You probably have the Eclipse Project build path configured to use absolute library references. When you try to run your runnable jar, the jvm cannot find the required dependencies.
Edit:
If you want to export your software as a RUNNABLE jar file, then the jar must contain a MANIFEST file which specifies the dependencies and main class. Example:
Manifest-Version: 1.0
Main-Class: com.example.Main
Class-Path: lib1.jar lib2.jar
(assuming your main class is com.example.Main)
In order to run your runnable jar file, place lib1 and lib2 on the same directory as your runnable jar and run:
java -jar myJar.jar
Otherwise you could just compile your main class and run it like this (assuming lib1 and lib2 are copied into a lib/ dir on your main class root path):
java -cp '.:/libs/*.jar' com.example.Main
You could also use a dependency manager tool such as maven and configure your build to create an "uberJar":https://maven.apache.org/plugins/maven-shade-plugin/examples/includes-excludes.html
uberJars contain all your software dependencies in one heavy runnable jar file.
Hope this helps.
Related
This is my MainBot.java code:
public class MainBot {
public static void main(String[] args) {
new MainBot("my_private_token");
}
public MainBot(String token) {
// do stuff
}
}
I have the following problem: When I try to execute the .jar file generated by IntelliJ, I get the following error:
could not find or load main class: MainBot
But when I look in the .jar file using WinRAR, I see this:
The MainBot.class file is there! The manifest file in the META-INF/ folder looks like this:
Manifest-Version: 1.0
Main-Class: MainBot
And the the META-INF folder looks like this:
What did I do wrong? When exporting, I select the correct main file in INTELLIJ, add the META-INF directory to resources/ and then I build my artifact. How come that The MainBot file cannot be found, when it is there?! I also tried playing arond with the MAINFEST.MF file and tried changing the Main-Class to ../MainBot or something, but none of that worked.
EDIT: This is the artifact under Project Structure | Artifacts
The META-INF folder in your generated Jar has these 2 files -
SIGNINGGC.RSA
SIGNINGGC.SF
I assume that you are not signing the Jar. Then, these files must be coming from one of your dependancies when you are creating a Fat Jar. If any of your dependancies has a Signed Jar, then it could result into that could not find or load main class: exception.
You can quickly find if this is the issue by removing those files with this command (referenced from here) and try and run the code -
zip -d yourjar.jar 'META-INF/*.SF' 'META-INF/*.RSA' 'META-INF/*.DSA'
IntelliJ shows 2 Options while generating Jar. The first one will generate a Fat Jar. The other option will keep the other library jars intact and link with them using Manifest file.
Assuming all you need is to run your code, use the second option in the Create Jar from Modules Dialog box.
I attempted to reproduce the error using a sample application that uses gradle, following this tutorial, but I couldn't. The sample application has a module named io.github.devatherock.example, which holds the module-info.java file and a package named io.github.devatherock.example, which contains the main class MainBot.java. I have listed the main class as io.github.devatherock.example.MainBot in gradle which produces a jar file with below manifest:
Manifest-Version: 1.0
Main-Class: io.github.devatherock.example.MainBot
The jar executes without any error. In the IDE, the structure of the source code looks like below:
In Windows
after generating jar file, in generated folder run command
7z d yourjar.jar META-INF/*.SF META-INF/*.RSA META-INF/*.DSA -r
you must installed 7zip and added enviorment path
I'm creating a new project that run as a Java application(.jar), but I am confused about how to package the lib folder into the final jar file.
And I try to use Maven, but did not found some eligable plugins.
The project structure is here
first, I try to package with IDEA's build Artifact. it will extract all jar file into final jar and create a MANIFEST file, but the impact is there are some file like "*.SF, *.RSA", it destory the java -jar xxx.jar, But we can solve it by delete these .sf/.rsa file. Next problem occur, cause I use some springframework dependency, when extract these jar file, they will create a file like spring.handles, but its not complete.
second, I try to use MAVEN. I use the maven-jar-plugin maven-compiler-plugin maven-dependency-plugin to copy all jar file into final jar, and create the correct MANIFEST file. BUT a java.lang.NoClassDefFoundError occur, I am DEAD!!!
So, the actual question is how can I package the lib folder into final executable jar???
My groovy (ant1.8.1 for build)project was build in jdk1.5 and now i am making some changes and upgrading to jdk1.8 .
When i build and make jar ,it works fine from the folder where code is in eclipse.
but when copy that jar and try to run get below-
Error :could not find or load main class Run.
Rest all jars are as below(same as used in jdk5)
groovy-all-1.6.9.jar
commons-codec-1.4.jar
commons-httpclient-3.0-rc4.jar
commons-logging-1.1.1.jar
commons-net-2.0.jar
lib/log4j-1.2.15.jar
jtds-1.2.5.jar
httpmime-4.0.1.jar
When you say "run", I understand you mean something like:
java -jar MyJar.jar
You should check your MANIFEST file inside the JAR and make sure your Main-Class is defined as you need.
Main-Class: pakage.name.ClassName.class
And the corresponding pakage.name.ClassName.class exists in your jar file (or is included in any of the libraries accessible through classpath)
Check this anyway Setting application entry point
Using Eclipse I created some parser classes I want to provide to another project as a jar archive for validation purposes. So the parser project look like this:
ParserProject
- src
-- com.package.x
--- ClassA
--- ClassB
- lib
-- external1.jar
-- external2.jar
The ClassA and ClassB use the external jar archives, like Jackson or some Apache commons. To provide the functionality to another project, I exported the entire project as jar archive and executable jar archive (Right click on project > Export... > Java > JAR file > Select all files and "Export generated class files and resources" > Finish).
The jar file is created without any errors. When I use the parserproject.jar in my validation project, I can access all my methods using auto completion, but when I run the validation project, I get a java.lang.ClassNotFoundException: com.fasterxml.jackson.core.JsonParseException.
Now three strange things:
All jackson jars are included in the parser project. Besides, I can run a main() method in the parser project and everything works fine, no ClassNotFoundException occurs.
When I add the parserproject.jar to my validation project in the class path and open the jar archive in the Package Explorer, the parserproject.jar seems to contain all jars it needs.
For the executable jar archive, all required external jars are contained in the MANIFEST.MF (Package Explorer > validation project > Referenced Libraries > + besides parserproject.jar > META-INF > MANIFEST.MF). It looks like this:
Manifest-Version: 1.0
Rsrc-Class-Path: ./ json-20140107.jar jackson-annotations-2.5.4.jar ja
ckson-core-2.5.4.jar jackson-databind-2.5.4.jar commons-io-2.4.jar co
mmons-validator-1.3.1.jar slf4j-api-1.7.5.jar slf4j-log4j12-1.7.5.jar
json-schema-validator-2.2.6.jar jackson-module-jsonSchema-2.4.4.jar
juniversalchardet-1.0.3.jar snakeyaml-1.15.jar commons-beanutils-1.7.
0.jar commons-digester-1.6.jar commons-logging-1.0.4.jar joda-time-2.
8.1.jar jopt-simple-4.6.jar jsr305-3.0.0.jar json-schema-core-1.2.5.j
ar libphonenumber-6.2.jar jackson-coreutils-1.8.jar commons-lang-2.6.
jar guava-16.0.1.jar msg-simple-1.1.jar btf-1.2.jar mailapi-1.4.3.jar
uri-template-0.9.jar
Class-Path: .
Rsrc-Main-Class: com.package.SchemeValidator
Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader
I get the exception if and only if I use the generated jar file in my validation project. In case I get rid of the parserproject.jar and define a dependency to the ecplise parser project instead (Right click on validation project > Properties > Java Build Path > Projects) I do not get the ClassNotFoundException.
So now my question is, how I should export the jar so that every class is found. Thank you!
Eclipse only takes care of the compile-time dependencies while generating a .jar
Since your generated .jar can be moved to virtually anywhere, the dependencies must again be present during execution time.
You have two options:
Execute your jar with the -jar option, while leaving all
dependencies in the same folder. Since your manifest uses "./" as classpath, this means all dependencies must be on the same directory you are executing your jar from. NOTE classpath is relative to the directory you are executing from, not the directory the file is on.
Execute your jar withour the -jar option, and specify the -cp option to point to the dependencies, and the specify the main class.
java -cp "<path to your jar>;<path to dependency 1>;<path to dependency 3>[;...]" <your main class>
You might consider creating a so called fat jar which will contain all the needed classes. For example: http://fjep.sourceforge.net/
If you do not want to go through the hassle of managing all the depencencies by yourself, consider using a build tool like
Maven https://maven.apache.org/ or Gradle https://gradle.org/.
I am currently trying to make a Jar with all my libraries included.
What I have done.
I have created folders like this :
main folder
class (which contain all my classes)
ressources (containing all my libraries : mongo, jedis...)
MANIFEST.MF
My main class is named process.
My manifest is like this:
Main-Class: process
Class-Path: ressources\commons-pool-1.5.6.jar ressources\jedis-2.0.0.jar resources\mongo-2.6.3.jar class
I have generated the JAR with this command :
jar cvmf MANIFEST.MF process.jar class/*.class ressources/*.jar
My problem : When executing the JAR I have still the message
Exception in thread "main" java.lang.NoClassDefFoundError: process
Any ideas ?
Are you using eclipse? If yes, it have an option in export to export libraries together with jar..
with netbeans, I dont know how to do it.
You could build your jar with Ant using zipfilesets to copy in the content of the other jars (rather than the jars themselves), or you could take a look at jarjar which does that and more.
Eclipse: You have to add the external jar files to the build.properties, otherwise they are no tpart of the generated jar file.
Ar the libraries included in the jar file, you have generated?