# HG changeset patch # User rfield # Date 1486579396 28800 # Node ID 868af3718a21b3ae44205d38fa1e5d02e8a27be3 # Parent 7193f6ef25dbde5e7101b0314eea580766b848b6 8173845: JShell API: not patch compatible Reviewed-by: jlahoda diff -r 7193f6ef25db -r 868af3718a21 langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java --- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java Wed Feb 08 09:12:45 2017 -0800 +++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java Wed Feb 08 10:43:16 2017 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,8 +44,10 @@ import java.util.function.BiFunction; import java.util.function.Consumer; +import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Stream; +import javax.tools.StandardJavaFileManager; import jdk.internal.jshell.debug.InternalDebugControl; import jdk.jshell.Snippet.Status; import jdk.jshell.spi.ExecutionControl.EngineTerminationException; @@ -92,6 +94,7 @@ final BiFunction idGenerator; final List extraRemoteVMOptions; final List extraCompilerOptions; + final Function fileManagerMapping; private int nextKeyIndex = 1; @@ -115,6 +118,7 @@ this.idGenerator = b.idGenerator; this.extraRemoteVMOptions = b.extraRemoteVMOptions; this.extraCompilerOptions = b.extraCompilerOptions; + this.fileManagerMapping = b.fileManagerMapping; try { if (b.executionControlProvider != null) { executionControl = b.executionControlProvider.generate(new ExecutionEnvImpl(), @@ -171,6 +175,7 @@ ExecutionControlProvider executionControlProvider; Map executionControlParameters; String executionControlSpec; + Function fileManagerMapping; Builder() { } @@ -365,6 +370,28 @@ } /** + * Configure the {@code FileManager} to be used by compilation and + * source analysis. + * If not set or passed null, the compiler's standard file manager will + * be used (identity mapping). + * For use in special applications where the compiler's normal file + * handling needs to be overridden. See the file manager APIs for more + * information. + * The file manager input enables forwarding file managers, if this + * is not needed, the incoming file manager can be ignored (constant + * function). + * + * @param mapping a function that given the compiler's standard file + * manager, returns a file manager to use + * @return the {@code Builder} instance (for use in chained + * initialization) + */ + public Builder fileManager(Function mapping) { + this.fileManagerMapping = mapping; + return this; + } + + /** * Builds a JShell state engine. This is the entry-point to all JShell * functionality. This creates a remote process for execution. It is * thus important to close the returned instance. @@ -501,6 +528,7 @@ * @throws IllegalStateException if this {@code JShell} instance is closed. */ public void addToClasspath(String path) { + checkIfAlive(); // Compiler taskFactory.addToClasspath(path); // Runtime diff -r 7193f6ef25db -r 868af3718a21 langtools/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java --- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java Wed Feb 08 09:12:45 2017 -0800 +++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java Wed Feb 08 10:43:16 2017 -0800 @@ -165,7 +165,9 @@ } public MemoryFileManager(StandardJavaFileManager standardManager, JShell proc) { - this.stdFileManager = standardManager; + this.stdFileManager = proc.fileManagerMapping != null + ? proc.fileManagerMapping.apply(standardManager) + : standardManager; this.proc = proc; } @@ -185,6 +187,7 @@ } // Make compatible with Jigsaw + @Override public String inferModuleName(Location location) { try { if (inferModuleNameMethod == null) { @@ -203,6 +206,7 @@ } // Make compatible with Jigsaw + @Override public Iterable> listLocationsForModules(Location location) throws IOException { try { if (listLocationsForModulesMethod == null) { diff -r 7193f6ef25db -r 868af3718a21 langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiDefaultExecutionControl.java --- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiDefaultExecutionControl.java Wed Feb 08 09:12:45 2017 -0800 +++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiDefaultExecutionControl.java Wed Feb 08 10:43:16 2017 -0800 @@ -33,6 +33,7 @@ import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -97,7 +98,8 @@ // Set-up the JDI connection JdiInitiator jdii = new JdiInitiator(port, - env.extraRemoteVMOptions(), remoteAgent, isLaunch, host, timeout); + env.extraRemoteVMOptions(), remoteAgent, isLaunch, host, + timeout, Collections.emptyMap()); VirtualMachine vm = jdii.vm(); Process process = jdii.process(); diff -r 7193f6ef25db -r 868af3718a21 langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiInitiator.java --- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiInitiator.java Wed Feb 08 09:12:45 2017 -0800 +++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiInitiator.java Wed Feb 08 10:43:16 2017 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016,2017 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,16 +66,20 @@ * Start the remote agent and establish a JDI connection to it. * * @param port the socket port for (non-JDI) commands - * @param remoteVMOptions any user requested VM options + * @param remoteVMOptions any user requested VM command-line options * @param remoteAgent full class name of remote agent to launch * @param isLaunch does JDI do the launch? That is, LaunchingConnector, * otherwise we start explicitly and use ListeningConnector * @param host explicit hostname to use, if null use discovered * hostname, applies to listening only (!isLaunch) - * @param timeout the start-up time-out in milliseconds + * @param timeout the start-up time-out in milliseconds. If zero or negative, + * will not wait thus will timeout immediately if not already started. + * @param customConnectorArgs custom arguments passed to the connector. + * These are JDI com.sun.jdi.connect.Connector arguments. */ public JdiInitiator(int port, List remoteVMOptions, String remoteAgent, - boolean isLaunch, String host, int timeout) { + boolean isLaunch, String host, int timeout, + Map customConnectorArgs) { this.remoteAgent = remoteAgent; this.connectTimeout = (int) (timeout * CONNECT_TIMEOUT_FACTOR); String connectorName @@ -96,6 +100,7 @@ argumentName2Value.put("localAddress", host); } } + argumentName2Value.putAll(customConnectorArgs); this.connectorArgs = mergeConnectorArgs(connector, argumentName2Value); this.vm = isLaunch ? launchTarget() diff -r 7193f6ef25db -r 868af3718a21 langtools/test/jdk/jshell/FileManagerTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/jdk/jshell/FileManagerTest.java Wed Feb 08 10:43:16 2017 -0800 @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test 8173845 + * @summary test custom file managers + * @build KullaTesting TestingInputStream + * @run testng FileManagerTest + */ + + +import java.io.File; +import java.io.IOException; + +import java.util.Set; +import javax.tools.ForwardingJavaFileManager; +import javax.tools.JavaFileObject; +import javax.tools.JavaFileObject.Kind; +import javax.tools.StandardJavaFileManager; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import static org.testng.Assert.assertTrue; + +@Test +public class FileManagerTest extends KullaTesting { + + boolean encountered; + + class MyFileManager extends ForwardingJavaFileManager + implements StandardJavaFileManager { + + protected MyFileManager(StandardJavaFileManager fileManager) { + super(fileManager); + } + + @Override + public Iterable list(Location location, + String packageName, + Set kinds, + boolean recurse) + throws IOException { + //System.out.printf("list(%s, %s, %s, %b)\n", + // location, packageName, kinds, recurse); + if (packageName.equals("java.lang.reflect")) { + encountered = true; + } + return fileManager.list(location, packageName, kinds, recurse); + } + + @Override + public Iterable getJavaFileObjectsFromFiles(Iterable files) { + return fileManager.getJavaFileObjectsFromFiles(files); + } + + @Override + public Iterable getJavaFileObjects(File... files) { + return fileManager.getJavaFileObjects(files); + } + + @Override + public Iterable getJavaFileObjectsFromStrings(Iterable names) { + return fileManager.getJavaFileObjectsFromStrings(names); + } + + @Override + public Iterable getJavaFileObjects(String... names) { + return fileManager.getJavaFileObjects(names); + } + + @Override + public void setLocation(Location location, Iterable files) throws IOException { + fileManager.setLocation(location, files); + } + + @Override + public Iterable getLocation(Location location) { + return fileManager.getLocation(location); + } + + } + + @BeforeMethod + @Override + public void setUp() { + setUp(b -> b.fileManager(fm -> new MyFileManager(fm))); + } + + public void testSnippetMemberAssignment() { + assertEval("java.lang.reflect.Array.get(new String[1], 0) == null"); + assertTrue(encountered, "java.lang.reflect not encountered"); + } + +} diff -r 7193f6ef25db -r 868af3718a21 langtools/test/jdk/jshell/MyExecutionControl.java --- a/langtools/test/jdk/jshell/MyExecutionControl.java Wed Feb 08 09:12:45 2017 -0800 +++ b/langtools/test/jdk/jshell/MyExecutionControl.java Wed Feb 08 10:43:16 2017 -0800 @@ -29,6 +29,7 @@ import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -78,7 +79,7 @@ + System.getProperty("path.separator") + System.getProperty("user.dir")); JdiInitiator jdii = new JdiInitiator(port, - opts, REMOTE_AGENT, true, null, TIMEOUT); + opts, REMOTE_AGENT, true, null, TIMEOUT, Collections.emptyMap()); VirtualMachine vm = jdii.vm(); Process process = jdii.process();