Is Java 1.6 in 10.5.8 just problematic?

Discussion in 'Mac Programming' started by ThinkandDrive, Jan 23, 2010.

  1. ThinkandDrive macrumors newbie

    Joined:
    Nov 2, 2006
    #1
    So, it's been years since I waded into something like this. Got out of the IT game and let my geek-brain atrophy.

    Running 10.5.8 on a Macbook, all system updates look good, etc.

    I am trying to run a command line program called calibre2opds that extracts the library info from a calibre ebook library and formats for web/Stanza clients. (Check out Calibre if you like ebooks. It's like iTunes for ebooks!)

    I am apparently running the same Java that the developer is, but am getting a runtime exception. The ONLY difference I can see is he says he's running build 1.6.0_17-b04-248-10M3025 while I am running build 1.6.0_17-b04-248-9M3125. What's the difference there?

    Code:
    daxiweida:bin joel$ java -version
    java version "1.6.0_17"
    Java(TM) SE Runtime Environment (build 1.6.0_17-b04-248-9M3125)
    Java HotSpot(TM) 64-Bit Server VM (build 14.3-b01-101, mixed mode)
    daxiweida:bin joel$ ./calibre2opds ~/Documents/eBooks/
    Exception in thread "main" java.lang.UnsupportedClassVersionError: Bad version number in .class file
    	at java.lang.ClassLoader.defineClass1(Native Method)
    	at java.lang.ClassLoader.defineClass(ClassLoader.java:676)
    	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
    	at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
    	at java.net.URLClassLoader.access$100(URLClassLoader.java:56)
    	at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
    	at java.lang.ClassLoader.loadClass(ClassLoader.java:317)
    	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:280)
    	at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
    	at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:375)
    daxiweida:bin joel$ 
    
    I have downloaded and run all 10.5 Java updates from ADC with no results.

    Just had a baby three weeks ago and I think the lack of sleep is making me miss something very obvious here.

    Here's the link to the forum where the developer was trying to help me, for reference. http://www.mobileread.com/forums/showthread.php?t=64095&page=5

    From my Googlin', it looks like Java 1.6 is troublesome in Leopard perhaps.
     
  2. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #2
    The error message being printed is unequivocal and undeniable: the JRE being run does not accept the class version that was compiled. That's the primary evidence, and everything else is secondary. You may well think that Java 1.6 is being executed, but the evidence of that error message strongly suggests otherwise.

    The plain unadorned 'java -version' command would be more useful evidence if the shell script ./calibre2opds were actually using a plain unadorned java command. Unfortunately, it doesn't.

    What it uses is an env-var JAVA_HOME to located a java command. Or it uses the output of 'which java'. Or other things. Read the shell script. I recommend starting at the end, to see the command-line, then finding what the different vars are set to by looking backwards.


    Step 1: find out exactly what command-line is being executed as the java command-line. It's the last line of the calibre2opds shell script. Drag and drop that file onto TextEdit.app to see it.

    I suggest adding -showversion to the command-line or as the JAVA_OPTS env-var. This will print the version and then run the program designated by the remaining command-line args. I strongly suspect that Java 1.6 is not being executed.

    Code:
    JAVA_OPTS="-showversion" ./calibre2opds ~/Documents/eBooks/
    

    Step 2: figure out what to change to make the calibre2opds script execute Java 1.6. Maybe use the command /usr/libexec/java_home, which emits the currently chosen value onto stdout. Man page:

    http://developer.apple.com/mac/library/DOCUMENTATION/Darwin/Reference/ManPages/man1/java_home.1.html

    Or, it looks like the calibre2opds script will accept an env-var of JAVA_VERSION, so maybe try this command:

    Code:
    JAVA_VERSION="1.6" ./calibre2opds ~/Documents/eBooks/
    
    Another possibility is to run the script with the -x option to shell, which should cause it to emit the expanded text of every command it executes. Then you can tell exactly what commands are really being executed. Probably something like:

    Code:
    sh -x ./calibre2opds ~/Documents/eBooks/
     
  3. ThinkandDrive thread starter macrumors newbie

    Joined:
    Nov 2, 2006
    #3
    Thanks! This is what I suspected.

    I ran into a hitch with your Step One suggestion but forcing JAVA_VERSION="1.6" seems to have worked like a charm. Now to figure out why my Macbook is lying to me. :rolleyes:
     
  4. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #4
    I'm glad it worked for you, but I don't think your Macbook is lying to you. I think you're asking it two things that you think should have the same answer, but in fact don't.

    If you really want the answer, then digging into exactly what the shell script does is the best approach. If you're not familiar with shell scripts, that could be more difficult. But if you're really interested and willing to pursue it, I'm sure we'd be willing to make specific suggestions about what to do.

    My first suggestion: open the calibre2opds script by dragging it onto TextEdit.app. Scroll to the end of the file. Where it says this:
    Code:
    exec "$JAVACMD" $JAVA_OPTS \
    
    change the word exec to echo, like so, then save it:
    Code:
    echo "$JAVACMD" $JAVA_OPTS \
    
    Then run this in Terminal:
    Code:
    ./calibre2opds ~/Documents/eBooks/
    
    It should print a bunch of text that looks like a big complex command-line. Copy and paste that text and post it here.
     
  5. ThinkandDrive thread starter macrumors newbie

    Joined:
    Nov 2, 2006
    #5
    Thanks. No, I don't really think it's lying to me. :)

    From what I understand, while I have 1.6 installed and maybe set as my default in Java Preferences, this script is likely using a different java.

    When I explicitly tell it to use Java version 1.6, it works fine.

    Here's the output when I echo rather than exec.

    Code:
    daxiweida:bin joel$ ./calibre2opds ~/Documents/eBooks/
    /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/bin/java -Xmx256m -classpath :/Applications/calibre2opds/etc:/Applications/calibre2opds/repo/com/gmail/dpierron/calibre/DataModel/1.0.3-SNAPSHOT/DataModel-1.0.3-SNAPSHOT.jar:/Applications/calibre2opds/repo/log4j/log4j/1.2.12/log4j-1.2.12.jar:/Applications/calibre2opds/repo/org/xerial/sqlite-jdbc/3.6.17.1/sqlite-jdbc-3.6.17.1.jar:/Applications/calibre2opds/repo/com/gmail/dpierron/Tools/1.0.3-SNAPSHOT/Tools-1.0.3-SNAPSHOT.jar:/Applications/calibre2opds/repo/junit/junit/4.7/junit-4.7.jar:/Applications/calibre2opds/repo/org/jdom/jdom/1.1/jdom-1.1.jar:/Applications/calibre2opds/repo/com/gmail/dpierron/calibre/OpdsOutput/1.0.3-SNAPSHOT/OpdsOutput-1.0.3-SNAPSHOT.jar -Dapp.name=calibre2opds -Dapp.pid=1081 -Dapp.repo=/Applications/calibre2opds/repo -Dbasedir=/Applications/calibre2opds Main /Users/joel/Documents/eBooks/
    daxiweida:bin joel$ 
    
    Am I right in assuming that, by itself, this script is somehow evoking a different JDK?
     
  6. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #6
    Yes, you're right. It's invoking this specific version of the java command:
    Code:
    /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/bin/java
    
    CurrentJDK is a symlink, and on Mac OS 10.5, it points to the 1.5 JVM, not 1.6. You can show it with this command-line (copy and paste into Terminal):
    Code:
    ls -l /System/Library/Frameworks/JavaVM.framework/Versions/
    
    Typical output should show CurrentJDK -> 1.5.

    This is because Mac OS doesn't switch between user-preferred Java versions by pointing the CurrentJDK symlink to different versions.

    The developer who said it works for him mentioned running on Snow Leopard, which doesn't have Java 1.5 at all, and simply points all the symlinks in Versions to 1.6. So the reason he got different results is because he has a very different JavaVM.framework contents than you (his Snow Leopard vs. your Leopard), despite having somewhat similar Java version numbers.

    By the way, the correct way to run with the user's "preferred Java" on Mac OS X is to execute /usr/libexec/java_home (if it exists) and use that as the JAVA_HOME value. In this case, I'm not sure that's a better approach overall, because it will still cause the shell script to fail if the user's preference isn't Java 1.6. On Leopard, Java 1.6 is only available to 64-bit Intel-based machines. There is no Java 1.6 for ppc or Intel-32-bit machines.

    One possibility may be to force the script to only use Java 1.6, by presetting the env-var in the script itself. Or if the classes don't require Java 6, then target compile them for Java 5, and then it won't matter.

    This is all just general advice on managing different OS and Java versions. It's not specific to calibre2opds.
     
  7. ThinkandDrive thread starter macrumors newbie

    Joined:
    Nov 2, 2006
    #7
    chown33,

    Thanks. I think I'm definitely seeing where things went awry here. I know the developer is following this thread and maybe he'll be able to use the /usr/libexec/java_home option for Darwin machines. Then it's a matter of explaining how to set the preference in the documentation.

    You've been an amazing help!!
     

Share This Page