username wrote:Can you provide the stack trace of the class version error? A class that isn't used does not have it's (class) constructor run.
The error was provided in a previous post in this same thread. From observation (but with no real theory behind it), it seems that if a project is compiled on J7 then it seems to generate the error immediately when running on J6. Regardless if the execution would actually run any J7 only code. This error does not seem to be catchable.
If the J7 only portion is compiled in a separate JAR file and then loaded from the J6 code using Class/Method/Invoke then it seems to run the J6 code to the point where it tries to load the J7 class from the external JAR file and then generates the same error. Again, this error does not appear catchable.
However, this means that if you do a Java Version check, to avoid calling the J7 code on a J7 machine, you can get a program to execute either J6 or J7 code based on the Java version available on the machine.
These findings are based on a Win8 Java 7 machine and a Ubuntu Java 6 Virtual Machine. The above results could be specific to the machines I am using and not necessarily true for all machines.
From the results, I am assuming that as soon as a J6 machine is asked to load a J7 class it will error out. This is why I was not able to put the J6 and J7 code into the same class, suing different methods, because (it seems) that the J6 machine detected J7 code in the class somewhere (even if it would not actually run it) and errored out.
Edit: Added below understanding
Here is my understanding of what is happening...it has been a log time since I had studied things like what exactly happens during a compile, so if my information is wrong please feel free to correct me.
When a class is part of a application package (i.e. is not a referenced class in an external JAR file) it is compiled by the compiler along with the rest of the application package. Since, at compile time, this class may or may not be used (depending on the conditions of runtime) the class must be added in any case. If the class is added as an external reference to a class is a separate JAR file then the compiler does not need to compile it when compiling the application package because the external JAR file is already compiled.
If the class includes any J7 code, it needs a J7 compiler because a J6 (or earlier) compiler will not be able to properly compile the J7 only code. However, if the class is compiled using J7 it seems that the compiler version is somehow added to the compile or the runtime has some way to detect which version of Java the class requires. It seems that the implementation of this version check is independent of the actual code run in the class. Thus even if the runtime invokes a method in the class that contains purely J6 code, if the class contains any J7 code elsewhere (or may just the fact that it was compiled using J7) renders the class incompatible with a J6 runtime.
This explains why, when the entire application package is compiled using J7, the application package will not run at all on a J6 machine...because the main class itself is J7. This also explains why, when the J7 class is called from an external JAR file while the calling application is J6 compiled, the application runs until the J7 class call. The runtime checks the compile version of the application, which is J6, and allows it to run on a J6 machine. When it tries to load the external JAR file class, which is J7, it fails the version check and generates the error.
This also would explain why the external JAR file can not contain both the J6 and J7 class. Since the external JAR file would need to be compiled using a J7 compiler (to support the J7 code), when the J6 application package class the external JAR file class it will see that it has been compiled using J7 (or contains J7 code) and thus will refuse to run it (giving the error) even if the method being invoked may not actually use any J7 code.
This all seems to make sense to me...the only odd behavior is that the error (when trying to load the J7 class) is not catchable. Correct me if I am wrong but if a try/catch structure specifies the generic Exception (as opposed to a specific Exceoption such as IOException) then it should catch all exceptions, no? In such a case using the try/catch structure around the class call should allow recovery when the class load fails. This does not seem to be happening. As a result the user needs to use something like a Java Version check to determine if the J7 class call is to be made or not (as opposed to using the try/catch structure to make that decision).