Friday, 14 October 2011

Glassfish and Tomcat Problems with Java 7

Now that Java 7 is released (finally!), we've had a few reports of problems with our training courses that are using Tomcat or Glassfish.

Both Tomcat and Glassfish are running on top of the Java Runtime (the JVM) which is pointed to by your system's environment variables. When you install Java 7, your system should be updated to be using the version 7 JVM, which Tomcat and Glassfish should run on without problems.

However, some people are finding that after installing Java 7, the compiler is working just fine in their IDE, but at runtime their Tomcat is reporting errors such as the following (You may have to check carefully in the logs for these errors):

Exception in thread "main" java.lang.UnsupportedClassVersionError
or:
java.lang.VerifyError: Expecting a stackmap frame (followed by something scary looking).
Both errors point to that although your code was compiled using version 7, the runtime of your Tomcat or Glassfish is still on version 6 (or older), and eventually this will lead to a crash.

As a check, fire up a command prompt window (I'm assuming you're on Windows, these are the only reports we've had so far), and type the command:

java -version
This will give the runtime version (note that 1.7 means Java 7 and 1.6 means Java 6 - confusing huh?)

If you're seeing the wrong version, I cannot explain why this is happening because I've tried to replicate the situation myself but for me everything installed just fine.

A quick fix is to copy the file called "java.exe" from the directory in which you installed Java 7 (this is often c:\program files\java\jdk1.7.x\bin), across to the c:\windows\system32 directory (you will need to overwrite what is already there). It is probably also wise to copy across the javac and javaw exe files to the same directory.

Now try java -version again, you should now see version 1.7.

A Further Step for Glassfish 3.0 Users

I've discovered that a further step is needed if you're running on Glassfish 3.0. The startup script invokes a script in the glassfishv3/glassfish/config directory, called "asenv.bat". Bizarrely, in Glassfish 3, this script hardcodes the location of the JVM in the final line of the script.

Find the following instruction:

set AS_JAVA=C:\Program Files\Java\jdk1.6.0_25
You can safely delete this line. If the AS_JAVA variable isn't set, the startup script falls back to using just plain "java" to run the JVM (which will now be version 7).

(If you're interested, the reason the copy to system32 works is that your system PATH always includes the /windows/system32 directory. The Java installation program actually drops the JVM and Compiler into this directory, so they will always be found on the command line and by any tools wanting to run a JVM, such as Tomcat. I suspect that for some reason, some installations fail to make the copy and so you're left with the old version.)

8 comments:

  1. asenv.bat or asenv.conf are the right files to edit to force GlassFish to use a given version of Java but you should really be using GlassFish 3.1.1 which is the version supported on Java 7.

    ReplyDelete
  2. Yes, good point the easy way is to upgrade to Glassfish 3.1.1.

    Anyone wanting to do that for our course will need to be aware of the bug 17295 as described in my earlier blog post.

    ReplyDelete
  3. Sir, I am currently taking the JavaEE course. I am on chapter 4 (Calling EJBs and JNDI). I am able to call the ejb only if I create the client class in the same project. I could not figure out how can I access the remote ejb if I create a new project (Client Project)? No matter what I do, the lookup fails from the Client project and its unable to find the ejb. This is what I have tried

    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "????? for glassfish you are using in the videos");
    env.put(Context.PROVIDER_URL, "???????(how do I find out what is the URL?)");
    Context jndi = new InitialContext(env);

    Please advise.

    ReplyDelete
  4. Hi Faraz,

    Please send us a support request through the "Contact Us" link on the virtualpairprogrammers.com website. The guys there will lead you through the steps to get it working.

    The two parameters will be the same as when you had the client in the same project (assuming your EJB is located on the same computer as the client?) Perhaps you're running on separate computers, in which case you will need the IP address in the URL.

    As I say, send in a support request and we'll look at everything for you.

    ReplyDelete
  5. Richard, I didn't follow your advice and use glassfish3 that you provided. I used glassfish4. However, I have had no problems until Ch13 of the JavaEE course. The ejb.jar file will deploy successfully and run. The switch to the webapp.jar file however is not working. It will not deploy successfully. I have been looking in the log files and haven't yet found anything. Can I email you the zipped project?

    ReplyDelete
  6. Hi Joe, could you send in a support call through the contact page at virtualpairprogrammers.com? We'll be able to deal with it ASAP then. It might also be worth trying to deploy on GF 3 (you can install both but only run one at a time); the error handling is much better and sometimes it's a really small but unreported problem.

    ReplyDelete
  7. Hello,

    I have java 1.7 installed and after executing java -version it says that i have java 1.7. Still i get this error:

    aused by: javax.ejb.TransactionRolledbackLocalException: Exception thrown from bean: java.lang.VerifyError: Expecting a stackmap frame at branch target 14
    Exception Details:
    Location:
    com/virtualpairprogrammers/staffmanagment/domain/Employee._persistence_get(Ljava/lang/String;)Ljava/lang/Object; @3: if_acmpne
    Reason:
    Expected stackmap frame at this location.
    Bytecode:
    0000000: 2b12 63a6 000b 2ab4 0065 b800 6bb0 2b12
    0000010: 6ca6 0008 2ab4 0032 b02b 126d a600 082a
    0000020: b400 30b0 2b12 6ea6 000b 2ab4 0034 b800
    0000030: 6bb0 2b12 6fa6 0008 2ab4 002e b001 b0

    Any ideas ?

    ReplyDelete
  8. Hi,

    This is always caused by the running virtual machine finding a bytecode instruction it doesn't understand - so it's caused by the version of the running JVM being less than the version of the JDK used to compile the code.

    So my guess is that your IDE is configured to use a version higher than 1.7. It might be a 1.7.x version, or it could be Java 1.8 (Java 8). Check the settings for the compiler in your IDE.

    It's best to send us a support call direct on the page at https://www.virtualpairprogrammers.com/contact.html - then one of our team will make sure it gets sorted out.

    ReplyDelete