From b8f10f6b5c3e5a2514cd363770fca07ada8f31c7 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 6 Apr 2016 14:51:34 +0200 Subject: [PATCH] reliably delegate all not explicitly imeplemented API calls from StandardJavaFileManager to JDK implementation object --- .../jetbrains/jps/javac/JavacFileManager.java | 38 +++++++++---------- .../org/jetbrains/jps/javac/JavacMain.java | 19 ++++++++-- 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacFileManager.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacFileManager.java index c717aa559149..e47e78dac183 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacFileManager.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacFileManager.java @@ -25,7 +25,6 @@ import javax.tools.*; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; @@ -109,26 +108,6 @@ class JavacFileManager extends ForwardingJavaFileManager paths) throws IOException { - try { - final Method forwardingMethod = StandardJavaFileManager.class.getMethod("setLocationFromPaths", Location.class, Iterable.class); - forwardingMethod.invoke(getStdManager(), location, paths); - } - catch (InvocationTargetException e) { - final Throwable cause = e.getCause(); - if (cause instanceof IOException) { - throw (IOException)cause; - } - throw new IOException("Error configuring " + location.getName(), cause); - } - catch (Throwable e) { - throw new IOException("Internal error: ", e); - } - } - public Iterable getJavaFileObjectsFromFiles(Iterable files) { return wrapJavaFileObjects(getStdManager().getJavaFileObjectsFromFiles(files)); } @@ -358,4 +337,21 @@ class JavacFileManager extends ForwardingJavaFileManager ourImplStatus = Collections.synchronizedMap(new HashMap()); + + JavaFileManager getApiCallHandler(Method method) { + Boolean isImplemented = ourImplStatus.get(method); + if (isImplemented == null) { + try { + JavacFileManager.class.getDeclaredMethod(method.getName(), method.getParameterTypes()); + isImplemented = Boolean.TRUE; + } + catch (NoSuchMethodException e) { + isImplemented = Boolean.FALSE; + } + ourImplStatus.put(method, isImplemented); + } + return isImplemented? this : getStdManager(); + } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java index c880924ea232..840403e2d0a0 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java @@ -30,9 +30,7 @@ import org.jetbrains.jps.incremental.LineOutputWriter; import javax.tools.*; import java.io.File; import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; +import java.lang.reflect.*; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; @@ -155,7 +153,7 @@ public class JavacMain { }; final JavaCompiler.CompilationTask task = compiler.getTask( - out, fileManager, diagnosticConsumer, _options, null, fileManager.getJavaFileObjectsFromFiles(sources) + out, wrapWithCallDispatcher(fileManager), diagnosticConsumer, _options, null, fileManager.getJavaFileObjectsFromFiles(sources) ); compilingTool.prepareCompilationTask(task, _options); @@ -191,6 +189,19 @@ public class JavacMain { return false; } + // methods added to newer versions of StandardJavaFileManager interfaces have default implementations that + // do not delegate to corresponding methods of FileManager's base implementation + // this proxy object makes sure the calls, not implemented in our file manager, are dispatched further to the base file manager implementation + private static StandardJavaFileManager wrapWithCallDispatcher(final JavacFileManager fileManager) { + //return fileManager; + return (StandardJavaFileManager)Proxy.newProxyInstance(fileManager.getClass().getClassLoader(), new Class[]{StandardJavaFileManager.class}, new InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + return method.invoke(fileManager.getApiCallHandler(method), args); + } + }); + } + private static boolean canUseOptimizedFileManager(JavaCompilingTool compilingTool) { // since java 9 internal API's used by the optimizedFileManager have changed return compilingTool instanceof JavacCompilerTool && !SystemInfo.isJavaVersionAtLeast("1.9");