ModuleHelper.java revision 3294:9adfb22ff08f
1/* 2 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.tools.javac.util; 27 28import java.lang.reflect.InvocationTargetException; 29import java.lang.reflect.Method; 30 31public class ModuleHelper { 32 /** The context key for the module helper. */ 33 protected static final Context.Key<ModuleHelper> moduleHelperKey = new Context.Key<>(); 34 35 /** Get the JavaCompiler instance for this context. */ 36 public static ModuleHelper instance(Context context) { 37 ModuleHelper instance = context.get(moduleHelperKey); 38 if (instance == null) 39 instance = new ModuleHelper(context); 40 return instance; 41 } 42 43 public ModuleHelper(Context context) { 44 context.put(moduleHelperKey, this); 45 Options options = Options.instance(context); 46 allowAccessToInternalAPI = options.isSet("accessInternalAPI"); 47 } 48 49 final boolean allowAccessToInternalAPI; 50 51 private void exportPackageToModule(String packageName, Object target) 52 throws ClassNotFoundException, NoSuchMethodException, IllegalArgumentException, 53 InvocationTargetException, IllegalAccessException { 54 if (addExportsMethod == null) { 55 Class<?> moduleClass = Class.forName("java.lang.reflect.Module"); 56 addExportsMethod = moduleClass.getDeclaredMethod("addExports", 57 new Class<?>[] { String.class, moduleClass }); 58 } 59 addExportsMethod.invoke(from, new Object[] { packageName, target }); 60 } 61 62 static final String[] javacInternalPackages = new String[] { 63 "com.sun.tools.javac.api", 64 "com.sun.tools.javac.code", 65 "com.sun.tools.javac.comp", 66 "com.sun.tools.javac.file", 67 "com.sun.tools.javac.jvm", 68 "com.sun.tools.javac.main", 69 "com.sun.tools.javac.model", 70 "com.sun.tools.javac.parser", 71 "com.sun.tools.javac.platform", 72 "com.sun.tools.javac.processing", 73 "com.sun.tools.javac.tree", 74 "com.sun.tools.javac.util", 75 76 "com.sun.tools.doclint", 77 }; 78 79 public void addExports(ClassLoader classLoader) { 80 try { 81 if (allowAccessToInternalAPI) { 82 if (from == null) { 83 if (getModuleMethod == null) { 84 getModuleMethod = Class.class.getDeclaredMethod("getModule", new Class<?>[0]); 85 } 86 from = getModuleMethod.invoke(getClass(), new Object[0]); 87 } 88 if (getUnnamedModuleMethod == null) { 89 getUnnamedModuleMethod = ClassLoader.class.getDeclaredMethod("getUnnamedModule", new Class<?>[0]); 90 } 91 Object target = getUnnamedModuleMethod.invoke(classLoader, new Object[0]); 92 for (String pack: javacInternalPackages) { 93 exportPackageToModule(pack, target); 94 } 95 } 96 } catch (Exception e) { 97 // do nothing 98 } 99 } 100 101 // a module instance 102 private Object from = null; 103 104 // on java.lang.reflect.Module 105 private static Method addExportsMethod = null; 106 107 // on java.lang.ClassLoader 108 private static Method getUnnamedModuleMethod = null; 109 110 // on java.lang.Class 111 private static Method getModuleMethod = null; 112} 113