Lincoln casino mobile no deposit bonus. Carrot weather 1 3 3. To help future weary souls out, here are the Google-friendly queries for what we'll be talking about in this post:
- java.lang.NoClassDefFoundError: java/lang/reflect/Executable
- java.lang.ClassNotFoundException: java.lang.reflect.Executable
# rpm -ivh jdk-8u191-linux-x64.rpm # rpm -ivh jdk-11.0.1linux-x64bin.rpm Or this can be installed using yum command as well. Step 2: Extract the downloaded tar file and move to /usr. Learn how to use the JDK to write applications for a wide range of environments. Hack on the JDK itself, right here in the OpenJDK Community: Browse the code on the web, clone a Mercurial repository to make a local copy, and contribute a patch to fix a bug, enhance an existing component, or define a new feature. RapidWeaver 8.3 Crack Mac is the front-end web designing application without any coding. So, Create the professional looking website easily within the minutes. You don't have to need knowledge about code. Connector/J 5.1 is also a Type 4 pure Java JDBC driver that conforms to the JDBC 4.2 specification. It provides compatibility with all the functionality of MySQL 5.6, 5.7, and 8.0. Connector/J 5.1 is covered by its own manual.
tldr: if you want to use -source 1.6
/-target 1.6
(or 1.7), then compile with the JDK 1.6 or JDK 1.7, otherwise you risk newer/Java 1.8-only classes sneaking into the bytecode.
Overview
The other day, I built a trunk version of GWT with my machine's default JDK, JDK 1.8.
GWT uses Ant/javac
to build, with the -source 1.6
and -target 1.6
flags set. Previously, I had thought this was a very safe/normal thing to do.
However, when running this built-with-1.8 version GWT on a JDK 1.7 JVMs, an exception occurred:
Normally these sorts of errors are expected when a library uses new JDK 1.8 methods/classes. Then all downstream users also have to use JDK 1.8.
However, in this case, the GWT source code doesn't reference Executable
anywhere. The GWT code base is really supposed to be JDK 1.7 compatible.
What Is java.lang.reflect.Executable
anyway?
Turns out Executable
is the new base class for java.lang.reflect.Method
and java.lang.reflect.Constructor
in JDK 1.8.
Before Java 8, the base class of Method
and Constructor
was AccessibleObject
. Echofon 1 8 0.
Granted, in Java 8, AccessibleObject
is still a base class of Method
and Constructor
, it's just that Executable
was inserted between AccessibleObject
and Method
and Constructor
.
Which, I don't know, changing base classes seems kinda risky, but they kept the old one, so I guess it seems innocent enough.
But Now Who Referenced Executable
?
So, I was still very confused; the GWT code base doesn't know anything about Executable
. Sure, it uses Method
and Constructor
a lot, as part of normal reflection code. But no Executable
.
A cursory javap -c -constants
of every GWT .class
file showed no reference, no cast, to Executable
.
Looking back at the offending stack trace, the last method in the stack trace, JavaDispatchImpl.getMethod
looks innocent:
The instanceof Method
check passes as true, but the stack trace doesn't get into MethodAdaptor
, it first goes off and loads Executable
, which fails and we end up stuck.
Look More Closely
Given the JVM was about to call into MethodAdaptor
, and that it typically loads the dependencies referenced by a class the first time that the class is loaded, I got more suspicious about MethodAdaptor
s dependencies.
It turns out javap
has a verbose flag, so trying that:
Resulted in a lot of interesting output, but most pertinently, we finally found the smoking gun:
Notice the very last line: stack = [ class java/lang/reflect/Executable ]
.
Rapidweaver 8 1 7 download. What?!
Here is the source of getUnderlingObject
:
It's very tiny. And no reference to Executable
.
What's a Stack Map Table?
Explain what the Stack Map is…
Here are some interesting links:
Reproducing It
Okay, so, sure, this problem happens in the large GWT codebase, but can we reproduce it?
It turns out, yes, it's very easy. Here is a simple, standalone Java file to reproduce this behavior, Foo.java
:
So, we'll start out compiling with JDK 1.8:
It compiles. And, if we look at the bytecode, our stack verification data looks just fine:
It's using AccessibleObject
, which will work in a JDK 1.7 JVM.
However, when we run Foo
when JDK 1.7, it actually fails, although due to the typical major.minor
mismatch error: Silkypix jpeg photography 9 2 14 0.
Okay, fair enough, so let's compile with -source 1.7
and -target 1.7
:
Agh! It worked fine, until we ran with JDK 1.7, and we got the Executable
error. And, sure enough, the offending Executable
reference is back in the bytecode:
It seems like the JDK 1.8 compiler must have different algorithms for calculating the Stack Map Table, and when set to -source 1.7
, it changes to an algorithm, that, ironically, picks a different type (Executable
instead of AccessibleObject
) for the table even though that type won't be available on JDK 1.7.
How To Avoid This: Option 1
Astute readers might have noticed the tip off go by; javac
warns about using the default (JDK 1.8) bootstrap classpath when compiling with source
/target
flags.
This is basically javac
warning us that, right, it knows this might happen–we're giving it a JDK 1.8 standard library, and expecting the compiler to 'just know' not to include references to any 1.8-only classes (whether due to internal decisions like this stack map, or even to user-code level decisions like calling JDK 1.8-only methods).
The javac
compiler, understandably, doesn't really have this 'what's in 1.7 vs. 1.8' metadata, so it is requesting that we override the bootstrap classpath, and make sure we're passing in a standard library that matches our source
and target
flags.
And, it turns out, if we heed the warning and use the bootstrap classpath:
Then order is restored to the world, and we can run 1.8-compiled classes on both JDK 1.8 and JDK 1.7.
The bytecode has gone back to only knowing about AccessibleObject
:
As (I assume), even though javac
is using it's 'JDK 1.7' algorithm for the Stack Map Table, Executable
isn't even on the classpath at all, for it to find and reference. So the algorithm ends up with AccessibleObject
instead, which is what we want.
What is odd about this option, ensuring to pass the -bootclasspath
, is that, previously, I thought the whole point of compiling with -source
/-target
was to use them when you did not have old JVMs installed, but still needed to target their platforms.
This is showing saying that, even if you're using a JDK 1.8 compiler, to avoid gotchas like this NoClassDefFoundError
, even with codebases that look 100% JDK 1.7 compatible, you need to use the bootclasspath
to ensure javac
only uses 1.7-available classes in the resulting bytecode.
How To Avoid This: Option 2
Rapidweaver 8 1 7 Jdk Iso
Just compile with JDK 1.7.
If you have to have the bootstrap classpath anyway, might as well set JAVA_HOME
to a JDK 1.7 install and be done with it.
Uninstalling The Software
This is what I did for my GWT trunk build, and it quickly went back to working as expected.