[ 
https://issues.apache.org/jira/browse/PIG-5387?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16838353#comment-16838353
 ] 

Nandor Kollar commented on PIG-5387:
------------------------------------

[~knoguchi], [~rohini] the class loading related changes is an ugly hack which 
I'm not proud of, but I didn't find any easy fix which is compatible with Java 
11 as well as Java 8, and this one seems to work. Fortunately it is only a test 
problem, not a production code issue. Until Java 8 the system class loader 
([AppClassLoader|https://github.com/openjdk/jdk/blob/jdk8-b120/jdk/src/share/classes/sun/misc/Launcher.java#L259])
 extends URLClassLoader, thus casting and registering the jar at runtime works 
fine. This has changes in Java 11 (I think since Java 9, but didn't verify 
this): system class loader no longer extends URLClassLoader (see 
[here|https://github.com/openjdk/jdk11u/blob/master/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java#L151]).
 I tried to create a new URLClassLoader and set the Thread's context class 
loader to it, but Pig uses 
[getSystemResources|https://github.com/apache/pig/blob/trunk/src/org/apache/pig/PigServer.java#L575]
 to locate the jars, which will ask system classloader, for the locations, and 
won't find resources registered below it. That's why I came up with this hack: 
on Java 8 it will work as before, on Java 11, it will register the new 
URLClassLoader as the parent of system class loader, and will find the jars. I 
know that this is an ugly hack, I guess the correct answer to this problem 
would be Java 11 module loading, but to remain compatible with Java 8 we should 
either introduce several reflective invocations, or we should introduce 
something like Java 11 shim. I don't think either option pays off for a single 
test fix like this one. The only incompatibility in this case is the casting of 
system class loader to URLClassLoader, and since we don't do it in any other 
place apart from these two test classes, I don't think it causes any issue with 
registering commands in Pig. Refactoring registerNewResource to Utils class is 
a good idea, as well as adding a comment which briefly describes the 
aforementioned situation.

> Test failures on JRE 11
> -----------------------
>
>                 Key: PIG-5387
>                 URL: https://issues.apache.org/jira/browse/PIG-5387
>             Project: Pig
>          Issue Type: Bug
>    Affects Versions: 0.17.0
>            Reporter: Nandor Kollar
>            Priority: Major
>         Attachments: PIG-5387_1.patch
>
>
> I tried to compile Pig with JDK 8 and execute the test with Java 11, and 
> faced with several test failures. For example TestCommit#testCheckin2 failed 
> with the following exception:
> {code}
> 2019-05-08 16:06:09,712 WARN  [Thread-108] mapred.LocalJobRunner 
> (LocalJobRunner.java:run(590)) - job_local1000317333_0003
> java.lang.Exception: java.io.IOException: Deserialization error: null
>       at 
> org.apache.hadoop.mapred.LocalJobRunner$Job.runTasks(LocalJobRunner.java:492)
>       at 
> org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:552)
> Caused by: java.io.IOException: Deserialization error: null
>       at 
> org.apache.pig.impl.util.ObjectSerializer.deserialize(ObjectSerializer.java:62)
>       at 
> org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.PigGenericMapBase.setup(PigGenericMapBase.java:183)
>       at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:143)
>       at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:799)
>       at org.apache.hadoop.mapred.MapTask.run(MapTask.java:347)
>       at 
> org.apache.hadoop.mapred.LocalJobRunner$Job$MapTaskRunnable.run(LocalJobRunner.java:271)
>       at 
> java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
>       at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
>       at 
> java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
>       at 
> java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
>       at java.base/java.lang.Thread.run(Thread.java:834)
> Caused by: java.lang.NullPointerException
>       at org.apache.pig.impl.plan.Operator.hashCode(Operator.java:106)
>       at java.base/java.util.HashMap.hash(HashMap.java:339)
>       at java.base/java.util.HashMap.readObject(HashMap.java:1461)
>       at 
> java.base/jdk.internal.reflect.GeneratedMethodAccessor12.invoke(Unknown 
> Source)
>       at 
> java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>       at java.base/java.lang.reflect.Method.invoke(Method.java:566)
>       at 
> java.base/java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1160)
> {code}
> It deserialization of one of the map plan failed, it appears we ran into 
> [JDK-8201131|https://bugs.openjdk.java.net/browse/JDK-8201131]. I seems that 
> the workaround in the issue report works, adding a readObject method to 
> org.apache.pig.impl.plan.Operator:
> {code}
>     private void readObject(ObjectInputStream in) throws 
> ClassNotFoundException, IOException {
>         in.defaultReadObject();
>     }
> {code}
> solves the problem, however I'm not sure that this is the optimal solution.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to