-
-
Notifications
You must be signed in to change notification settings - Fork 925
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unable to use JRuby with google app engine due to use of sun.misc.Unsafe #2304
Comments
JRuby should be able to run without sun.misc.Unsafe, falling back on more-safe-but-less-fast code. Can you investigate where we're using it unconditionally? |
Absolutely, I'll dig in when i get a little bit of free time. In the mean time, here is the stack trace in case it's immediately obvious to someone else where the issue is. This occurred on a freshly created rails app, used warbler to make a war, then tried to run the exploded war with the local app engine dev server. I was using jruby 1.7.16.2, but tried a few other recent versions.
|
The feature detection logic itself triggers the rejection. I'm searching for techniques to detect Google's sandbox. The best option I've found so far is the |
I think the right fix here might be to expand the Exception catch around loading Unsafe; the reason this is percolating out and not falling back on non-Unsafe logic is because GAE is triggering NoClassDefFoundError (not catchable with "Exception") rather than a more typical ClassNotFoundException. I'm not sure why they decided to use an Error, since those are usually reserved for unrecoverable problems (OutOfMemoryError, StackOverflowError, NoClassDefFoundError when a statically-referenced class can't load, etc). There is a small risk that catching Throwable might mask other critical errors, so I think we should add an additional catch of NoClassDefFoundError rather than widening the existing catch. |
Here's a trivial patch for you to try, @jaydonnell: diff --git a/core/src/main/java/org/jruby/util/unsafe/UnsafeHolder.java b/core/src/main/java/org/jruby/util/unsafe/UnsafeHolder.java
index 652ff2d..afb1274 100644
--- a/core/src/main/java/org/jruby/util/unsafe/UnsafeHolder.java
+++ b/core/src/main/java/org/jruby/util/unsafe/UnsafeHolder.java
@@ -50,6 +50,9 @@ public final class UnsafeHolder {
return (sun.misc.Unsafe) f.get(null);
} catch (Exception e) {
return null;
+ } catch (NoClassDefFoundError ncdfe) {
+ // Google AppEngine raises NCDFE for Unsafe rather than CNFE
+ return null;
}
}
Clone JRuby, see BUILDING.md. |
@mdavidn Checking the property may be a reasonable fix, but it feels a bit hacky to me. I also don't like the idea of adding GAE-specific checks in our codebase, since there may be similar checks for other JVMs and clouds in the future...but we do already check for J9 (IBM's JVM) in places, so my point may be moot. For now I think we'll stick to the exception-based fallback and just make sure it handles NCDFE. |
I've pushed my patch to jruby-1_7 branch, since it should cover the NCDFE issue, and since all our Unsafe access goes through this same path. Give it a whirl from HEAD or wait for 1.7.18 in a few days. |
Hey @headius, this didn't work. The error gets thrown before the loadUnsafe() is executed so the catch for NoClassDefFoundError needs to be at every usage of UnsafeHolder which is obviously a bad solution. My Java is not great and I haven't been able to come up with a good solution. Any thoughts? |
Ah, so maybe that's why it was a NoClassDefFoundError - the class itself has fields and methods using Unsafe and Google's magic runtime is pretending it doesn't exist. So the code never even gets to the Class.forName call... maybe if it did get there, it would have thrown ClassNotFoundException instead [100% speculation]. What I would have done is to make my own Unsafe interface with a RealUnsafe and DummyUnsafe implementations, then in UnsafeHolder, loadUnsafe() would return one of those instead. As an added bonus, you wouldn't need all these "U == null" checks throughout the code. |
@trejkaz yeah, i went that route (DummyUnsafe) interface, and it got by this particular error. Unfortunately I ran into a number of other issues trying to run on app engine. At this point I'm debating whether it's worth the time to continue going down this path of trying to get jruby to work, or if I should give up on jruby on app engine altogether. |
Google App Engine does not allow use of sun.misc.Unsafe, and recent versions of JRuby appear to depend on it. Is there (or can there be) a workaround, or will JRuby be unusable on app engine going forward?
The text was updated successfully, but these errors were encountered: