Make use of Beans.instantiate optional - JDK-8047773
diff --git a/activation/src/main/java/javax/activation/CommandInfo.java b/activation/src/main/java/javax/activation/CommandInfo.java
index b3bd2bb..41fff46 100644
--- a/activation/src/main/java/javax/activation/CommandInfo.java
+++ b/activation/src/main/java/javax/activation/CommandInfo.java
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 1997-2015 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997-2017 Oracle and/or its affiliates. All rights reserved.
  *
  * The contents of this file are subject to the terms of either the GNU
  * General Public License Version 2 only ("GPL") or the Common Development
@@ -41,7 +41,10 @@
 package javax.activation;
 
 import java.io.*;
-import java.beans.Beans;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 
 /**
  * The CommandInfo class is used by CommandMap implementations to
@@ -97,8 +100,14 @@
     /**
      * Return the instantiated JavaBean component.
      * <p>
-     * Begin by instantiating the component with
-     * <code>Beans.instantiate()</code>.
+     * If the current runtime environment supports
+     * {@link java.beans.Beans#instantiate Beans.instantiate},
+     * use it to instantiate the JavaBeans component.  Otherwise, use
+     * {@link java.lang.Class#forName Class.forName}.
+     * <p>
+     * The component class needs to be public.
+     * On Java SE 9 and newer, if the component class is in a named module,
+     * it needs to be in an exported package.
      * <p>
      * If the bean implements the <code>javax.activation.CommandObject</code>
      * interface, call its <code>setCommandContext</code> method.
@@ -129,7 +138,7 @@
 	Object new_bean = null;
 
 	// try to instantiate the bean
-	new_bean = java.beans.Beans.instantiate(loader, className);
+	new_bean = Beans.instantiate(loader, className);
 
 	// if we got one and it is a CommandObject
 	if (new_bean != null) {
@@ -148,4 +157,86 @@
 
 	return new_bean;
     }
+
+    /**
+     * Helper class to invoke Beans.instantiate reflectively or the equivalent
+     * with core reflection when module java.desktop is not readable.
+     */
+    private static final class Beans {
+        static final Method instantiateMethod;
+
+        static {
+            Method m;
+            try {
+                Class<?> c = Class.forName("java.beans.Beans");
+                m = c.getDeclaredMethod("instantiate", ClassLoader.class, String.class);
+            } catch (ClassNotFoundException e) {
+                m = null;
+            } catch (NoSuchMethodException e) {
+                m = null;
+            }
+            instantiateMethod = m;
+        }
+
+        /**
+         * Equivalent to invoking java.beans.Beans.instantiate(loader, cn)
+         */
+        static Object instantiate(ClassLoader loader, String cn)
+                throws IOException, ClassNotFoundException {
+
+            Exception exception;
+
+            if (instantiateMethod != null) {
+
+                // invoke Beans.instantiate
+                try {
+                    return instantiateMethod.invoke(null, loader, cn);
+                } catch (InvocationTargetException e) {
+                    exception = e;
+                } catch (IllegalAccessException e) {
+                    exception = e;
+                }
+
+            } else {
+
+		SecurityManager security = System.getSecurityManager();
+		if (security != null) {
+		    // if it's ok with the SecurityManager, it's ok with me.
+		    String cname = cn.replace('/', '.');
+		    if (cname.startsWith("[")) {
+			int b = cname.lastIndexOf('[') + 2;
+			if (b > 1 && b < cname.length()) {
+			    cname = cname.substring(b);
+			}
+		    }
+		    int i = cname.lastIndexOf('.');
+		    if (i != -1) {
+			security.checkPackageAccess(cname.substring(0, i));
+		    }
+		}
+
+                // Beans.instantiate specified to use SCL when loader is null
+                if (loader == null) {
+                    loader = (ClassLoader)
+		        AccessController.doPrivileged(new PrivilegedAction() {
+			    public Object run() {
+				ClassLoader cl = null;
+				try {
+				    cl = ClassLoader.getSystemClassLoader();
+				} catch (SecurityException ex) { }
+				return cl;
+			    }
+			});
+                }
+                Class<?> beanClass = Class.forName(cn, true, loader);
+                try {
+                    return beanClass.newInstance();
+                } catch (Exception ex) {
+                    throw new ClassNotFoundException(beanClass + ": " + ex, ex);
+                }
+
+            }
+            return null;
+        }
+    }
 }