Fix Potential IllegalArgumentException

In the event multiple URLs were used for jar deployment,
an IllegalArgumentException would have been thrown.
Replaced problematic reflection call in favor of a sub-
class.

Change-Id: I7c9e1ec2c1541e7593dbc09dac52bfdc9e1cbec6
Reviewed-on: https://asterix-gerrit.ics.uci.edu/649
Reviewed-by: Till Westmann <tillw@apache.org>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
diff --git a/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/deployment/ClassLoaderJobSerializerDeserializer.java b/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/deployment/ClassLoaderJobSerializerDeserializer.java
index 60ff2d3..bcd90bd 100644
--- a/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/deployment/ClassLoaderJobSerializerDeserializer.java
+++ b/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/deployment/ClassLoaderJobSerializerDeserializer.java
@@ -20,7 +20,6 @@
 package org.apache.hyracks.control.common.deployment;
 
 import java.io.Serializable;
-import java.lang.reflect.Method;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.util.Collections;
@@ -38,7 +37,7 @@
  */
 public class ClassLoaderJobSerializerDeserializer implements IJobSerializerDeserializer {
 
-    private URLClassLoader classLoader;
+    private MutableURLClassLoader classLoader;
 
     @Override
     public Object deserialize(byte[] jsBytes) throws HyracksException {
@@ -76,13 +75,12 @@
             if (classLoader == null) {
                 /** crate a new classloader */
                 URL[] urls = binaryURLs.toArray(new URL[binaryURLs.size()]);
-                classLoader = new URLClassLoader(urls, this.getClass().getClassLoader());
+                classLoader = new MutableURLClassLoader(urls, this.getClass().getClassLoader());
             } else {
                 /** add URLs to the existing classloader */
-                Object[] urls = binaryURLs.toArray(new URL[binaryURLs.size()]);
-                Method method = classLoader.getClass().getDeclaredMethod("addURL", new Class[] { URL.class });
-                method.setAccessible(true);
-                method.invoke(classLoader, urls);
+                for (URL url : binaryURLs) {
+                    classLoader.addURL(url);
+                }
             }
         } catch (Exception e) {
             throw new HyracksException(e);
@@ -107,4 +105,16 @@
     public String toString() {
         return classLoader.toString();
     }
+
+    private static class MutableURLClassLoader extends URLClassLoader {
+
+        public MutableURLClassLoader(URL[] urls, ClassLoader classLoader) {
+            super(urls, classLoader);
+        }
+
+        @Override
+        protected void addURL(URL url) {
+            super.addURL(url);
+        }
+    }
 }