1

The directories in my jar files are like this:

in remote.jar

 -com
 -lib
 -META-INF

under META-INF is the file MANIFEST.MF:

Manifest-Version: 1.0
Class-Path: lib/*
Main-Class: com.xx.xx.Main

and all jars are under lib folder.

From the command line when i run java -jar remote.jar it gives me ClassNotFoundException, the class not found is in one of the jars under lib folder. If the main function does not reference any class in lib, the command line run with no problem.

My question is why it can not find the classes in jars under lib.

EDIT:

No nested folders under folder lib

Mike
  • 3,515
  • 10
  • 44
  • 67
  • possible duplicate of [java.lang.ClassNotFoundException when running java -jar (still unsolved)](http://stackoverflow.com/questions/1795452/java-lang-classnotfoundexception-when-running-java-jar-still-unsolved) – Wim Ombelets Nov 07 '13 at 09:24
  • 1
    on a side note: your title is incorrect – Wim Ombelets Nov 07 '13 at 09:24
  • Try changing the class path to `./lib/` – Choc13 Nov 07 '13 at 09:29
  • @Choc13 not work i tried. – Mike Nov 07 '13 at 09:38
  • I have successfully created an executable jar referencing third party jars using export in Eclipse. Eclipse then handled the creation of the MANIFEST.MF for me and added the necessary stuff to load jars from within a jar. – Choc13 Nov 07 '13 at 09:39
  • @Choc13 Sorry i use IDEA – Mike Nov 07 '13 at 09:43
  • Ah. I have never used IDEA, but just found this [link](http://blog.jetbrains.com/idea/2010/08/quickly-create-jar-artifact/) that might help you out. – Choc13 Nov 07 '13 at 09:45
  • @Choc13 ....I exactly followed the link you post, and create the jar, but can not run – Mike Nov 07 '13 at 09:47
  • Apologies. That link is just for creating a normal jar, not an executable one. Unfortunately, I could not find out how to achieve this in IntelliJ IDEA. Maybe it will be simpler to use Eclipse for this, although that is a bit of a pain just to create a runnable jar. – Choc13 Nov 07 '13 at 09:57
  • @Mike Please check out `One-Jar` from my answer. I haven't used it personally, but I read many people recommend it to create single executable jar. Otherwise, you could check http://stackoverflow.com/questions/2025607 , but I am not sure it is about executable jars either. – kiruwka Nov 07 '13 at 10:00
  • Yes i tried, my first try is to use One-Jar, and it works just fine, but i can't take it because it will build all dependencies in one jar which is so large in my project, so i have to build a customized version, with several class and a couple of used jars. – Mike Nov 07 '13 at 10:10
  • @Mike I am pretty sure One-Jar lets you configure which jars to pack and which will remain as run-time dependency (is that what you want ?) Also, you could take a loot at [Proguard](http://proguard.sourceforge.net/). It can extract and pack certain classes, not whole jars. – kiruwka Nov 07 '13 at 10:32
  • @Mike Do you use Maven ? It will let you pack your dependencies they way you want too. – kiruwka Nov 07 '13 at 10:38
  • Thanks for your reply, yes i use maven, i also went to see doc for one-jar but unfortunately did not find any info about "which jars to pack and which will remain as run-time dependency". – Mike Nov 07 '13 at 10:50
  • @Mike I guess you are right about lack of flexibility of One-Jar. Let's try to pack it with maven then. Have a look here : http://stackoverflow.com/questions/16222748 – kiruwka Nov 07 '13 at 11:02
  • @Mike +1 for the question too, although it seems quite common problem, I learned something new today. – kiruwka Nov 07 '13 at 11:20
  • @kiruwka thanks, i just tried JarSplice you said, it almost work but fail at last step, it said i have duplicated class in one jar, without this jar it could build but you know, can not find the class if needed to run. I'm trying Proguard... – Mike Nov 07 '13 at 11:30
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/40727/discussion-between-kiruwka-and-mike) – kiruwka Nov 07 '13 at 11:30

2 Answers2

2

The problem is that the Class-Path property in the manifest doesn't work how you think it does. See http://docs.oracle.com/javase/tutorial/deployment/jar/downman.html

Note: The Class-Path header points to classes or JAR files on the local network, not JAR files within the JAR file or classes accessible over internet protocols. To load classes in JAR files within a JAR file into the class path, you must write custom code to load those classes. For example, if MyJar.jar contains another JAR file called MyUtils.jar, you cannot use the Class-Path header in MyJar.jar's manifest to load classes in MyUtils.jar into the class path.

The simplest solution is to leave the classpath jars outside of your jar and to create a little batch file or shell script to construct the classpath and call your jar.

Ian Fairman
  • 625
  • 5
  • 11
1

I am afraid setting your MANIFEST Class-path will not let you successfully load classes from nested jars (i.e. within your jar as stated in the link from Ian's answer).
If you want to package single executable jar, your best options would be :

kiruwka
  • 9,250
  • 4
  • 30
  • 41
  • @EJP you are incorrect. Please see link from Ian's answer. `not JAR files within the JAR file or classes accessible over internet protocol` – kiruwka Nov 07 '13 at 09:36
  • @EJP - care to remove your downvote ? Please re-read my answer carefully before taking decisions. Thanks – kiruwka Nov 07 '13 at 09:39
  • 1
    not voted at all: i recommend changing the word "local" it's misleading and inaccurate. "nested" is much better – b.buchhold Nov 07 '13 at 09:44
  • Thank you so much for your continuous help to help me find the root cause of my problem, i learned much, it's an precious experience. – Mike Nov 07 '13 at 13:00