Skip to content
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

Java command - class resolving with Java 1.8 #459

Open
brunatm opened this issue Jan 9, 2017 · 3 comments
Open

Java command - class resolving with Java 1.8 #459

brunatm opened this issue Jan 9, 2017 · 3 comments

Comments

@brunatm
Copy link

brunatm commented Jan 9, 2017

Class is not correctly resolved in ScriptEvaluator() -> FastJavaScriptEngine.compile() call.
I have Java code snippet in java command:

byte[] bytes = (byte[]) record.getFirstValue("time");
long time = (Long)org.apache.phoenix.schema.types.PLong.INSTANCE.toObject(bytes);
. . .
return child.process(record);

When this is evaluated in JavaBuilder -> ScriptEvaluator I get exception:
javax.script.ScriptException: Cannot compile script: ... caused by java.lang.NoSuchMethodException: edu.umd.cs.findbugs.annotations.SuppressWarnings.eval(org.kitesdk.morphline.api.Record, com.typesafe.config.Config, org.kitesdk.morphline.api.Command, org.kitesdk.morphline.api.Command, org.kitesdk.morphline.api.MorphlineContext, org.slf4j.Logger)
at org.kitesdk.morphline.scriptengine.java.ScriptEvaluator.throwScriptCompilationException(ScriptEvaluator.java:141)
at org.kitesdk.morphline.scriptengine.java.ScriptEvaluator.(ScriptEvaluator.java:108)
at TestScriptEvaluator.main(TestScriptEvaluator.java:30)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
It fails when compiling to Java 1.8, ok when 1.6 is set. But 1.8 is required by project.

ScriptEvaluator builds up string representation of temporary Java class and calls FastJavaScriptEngine to compile it. FastJavaScriptEngine tries to find class where eval method is expected. This is the point of failure under 1.8 bytecode. Here classBytes is map of size 2 with edu.umd.cs.findbugs.annotations.SuppressWarnings and org.kitesdk.morphline.scriptengine.java.scripts.MyJavaClass1 classes. Logic of method parse() will load first of these classes which is unfortunately SuppressWarnings and so the exception NoSuchMethodException is throwed.
When analyzing this I located the SuppressWarnings appears because of line:
...org.apache.phoenix.schema.types.PLong.INSTANCE.toObject(bytes);
but I don't see any compilation warning which can happen here.
But that is not important for this issue.

ScriptEvaluator knows the name of class which contains command code snippet and can tell this to FastJavaScriptEngine so it doesn't have to search for class. This is also workaround I used in my case (via mainClass context attribute).

Please verify such behaviour when Java 1.8 is used and consider some fix.
I attached TestScriptEvaluator class which simulates this error.

https://gist.github.com/brunatm/2c7b8b7a56c4a4a5ca96167b9bdb2786

@whoschek
Copy link

The build (which also tests the java command) passes on java7 and java8 per https://travis-ci.org/kite-sdk/kite

Seems like this line "org.apache.phoenix.schema.types.PLong.INSTANCE.toObject(bytes)" requires the class edu.umd.cs.findbugs.annotations.SuppressWarnings on the classpath, and that SuppressWarnings class is missing on your classpath. Try adding the jar containing that SuppressWarnings class.

@brunatm
Copy link
Author

brunatm commented Jan 13, 2017

This class is successfully loaded in FastJavaScriptEngine.parse() (by Launcher$AppClassLoader) so it can't be missing on classpath. In other words calling org.apache.phoenix.schema.types.PLong.INSTANCE.toObject(bytes); itself in project is not problem (no missing class).
Yes, the SuppressWarnings class is loaded at the moment of .toObject() compilation but that shouldn't block ScriptEvaluator from running its code snippet (find temp. class MyJavaClass#).

(Besides that I don't see any JavaBuilder test in https://github.com/kite-sdk/kite/tree/master/kite-morphlines/kite-morphlines-core/src/test/java/org/kitesdk/morphline/stdlib)

@whoschek
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants