Reasonable handling of ScriptException thrown by JSR223 Rhino

I'm starting to come across dirty little secrets of what is actually very useful for the JSR223 scripting environment.

I use the built-in version of Rhino that comes with Java 6 SE, access to it through JSR223 ScriptingEngine , etc.

When I get an exception thrown by a Java object that I exported to a Javascript environment, it is a ScriptingException that wraps sun.org.mozilla.javascript.internal.WrappedException that wraps my real exception (like UnsupportedOperationException or something else)

ScriptingException returns null for getFileName () and -1 for getLineNumber (). But when I look at the message with the debugger, WrappedException has the correct file name and line number, it just does not publish it using getterExceptionException methods.

Great. Now what should I do? I do not know how I will use sun.org.mozilla.javascript.internal.wrappedException, which in any case is not publicly available.

+7
source share
1 answer

Argh. Java 6 Rhino does the same thing (does not publish the file name / line number / etc via ScriptingException methods) with sun.org.mozilla.javascript.internal.EvaluatorException and who knows how many other exceptions.

The only reasonable way I can think with is to use reflection. Here is my solution.

 void handleScriptingException(ScriptingException se) { final Throwable t1 = se.getCause(); String lineSource = null; String filename = null; Integer lineNumber = null; if (hasGetterMethod(t1, "sourceName")) { lineNumber = getProperty(t1, "lineNumber", Integer.class); filename = getProperty(t1, "sourceName", String.class); lineSource = getProperty(t1, "lineSource", String.class); } else { filename = se.getFileName(); lineNumber = se.getLineNumber(); } /* do something with this info */ } static private Method getGetterMethod(Object object, String propertyName) { String methodName = "get"+getBeanSuffix(propertyName); try { Class<?> cl = object.getClass(); return cl.getMethod(methodName); } catch (NoSuchMethodException e) { return null; /* gulp */ } } static private String getBeanSuffix(String propertyName) { return propertyName.substring(0,1).toUpperCase() +propertyName.substring(1); } static private boolean hasGetterMethod(Object object, String propertyName) { return getGetterMethod(object, propertyName) != null; } static private <T> T getProperty(Object object, String propertyName, Class<T> cl) { try { Object result = getGetterMethod(object, propertyName).invoke(object); return cl.cast(result); } catch (Exception e) { e.printStackTrace(); } return null; } 
+1
source

All Articles