]> source.dussan.org Git - aspectj.git/commitdiff
Adjust how classpath entries manipulated for Java9 support
authorAndy Clement <aclement@pivotal.io>
Fri, 20 Oct 2017 19:48:41 +0000 (12:48 -0700)
committerAndy Clement <aclement@pivotal.io>
Fri, 20 Oct 2017 19:48:41 +0000 (12:48 -0700)
Prior to this AspectJ would discard ignore the ClasspathEntry
objects built by JDT and just work with the classpath as a string,
driving the JDT FileSystem to rebuild classpath entries again at
a later date using the string. This is more complex in Java9 because
the string representation was losing whether some entries came in
via modulepath.  ClasspathEntry construction for modulepath entries
is non trivial (since the module-info must be processed).

The new version will cache some of the ClasspathEntry objects (those
built for modulepaths) and do more work on the AspectJ side building
classpath entries in general. It now passes these entries to a
different FileSystem entry point rather than the entry point that
takes a string path.

ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildManager.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/ConfigParser.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/StatefulNameEnvironment.java
org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjBuildManagerTest.java
org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjStateTest.java
org.aspectj.ajdt.core/testsrc/org/aspectj/tools/ajc/AjcTestCase.java
util/src/org/aspectj/util/SoftHashMap.java

index 4ab05c96896e1c65d02cf4556c67c34537b3b925..5577a01af7c2dce183331d0feac2bb4f1ba1697d 100644 (file)
@@ -37,6 +37,7 @@ import org.aspectj.bridge.ISourceLocation;
 import org.aspectj.bridge.Message;
 import org.aspectj.bridge.SourceLocation;
 import org.aspectj.bridge.context.CompilationAndWeavingContext;
+import org.aspectj.org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath;
 import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.aspectj.util.LangUtil;
 
@@ -277,6 +278,14 @@ public class AjdeCoreBuildManager {
                                both.addAll(configClasspath);
                                both.addAll(toAdd);
                                config.setClasspath(both);
+                               Classpath[] checkedClasspaths = config.getCheckedClasspaths();
+                               ArrayList<Classpath> cps = parser.handleClasspath(toAdd, compilerConfig.getProjectEncoding());
+                               Classpath[] newCheckedClasspaths = new Classpath[checkedClasspaths.length+cps.size()];
+                               System.arraycopy(checkedClasspaths, 0, newCheckedClasspaths, 0, checkedClasspaths.length);
+                               for (int i=0;i<cps.size();i++) {
+                                       newCheckedClasspaths[checkedClasspaths.length+i] = cps.get(i);
+                               }
+                               config.setCheckedClasspaths(newCheckedClasspaths);
                        }
                }
 
@@ -295,18 +304,18 @@ public class AjdeCoreBuildManager {
                }
 
                // Process the INPATH
-               mergeInto(config.getInpath(), compilerConfig.getInpath());
+               config.addToInpath(compilerConfig.getInpath());
                // bug 168840 - calling 'setInPath(..)' creates BinarySourceFiles which
                // are used to see if there have been changes in classes on the inpath
                if (config.getInpath() != null) {
-                       config.setInPath(config.getInpath());
+                       config.processInPath();
                }
 
                // Process the SOURCE PATH RESOURCES
                config.setSourcePathResources(compilerConfig.getSourcePathResources());
 
                // Process the ASPECTPATH
-               mergeInto(config.getAspectpath(), compilerConfig.getAspectPath());
+               config.addToAspectpath(compilerConfig.getAspectPath());
 
                // Process the JAVA OPTIONS MAP
                Map<String,String> jom = compilerConfig.getJavaOptionsMap();
@@ -347,17 +356,6 @@ public class AjdeCoreBuildManager {
                return config;
        }
 
-       private <T> void mergeInto(Collection<T> target, Collection<T> source) {
-               if ((null == target) || (null == source)) {
-                       return;
-               }
-               for (T next : source) {
-                       if (!target.contains(next)) {
-                               target.add(next);
-                       }
-               }
-       }
-
        /**
         * Helper method for configure build options. This reads all command-line options specified in the non-standard options text
         * entry and sets any corresponding unset values in config.
index fae1aadd3a8a8c1dec431cb33564d6705f0a72a0..c061208f0adcd1a5cc8e4bc71bfc0a9e029f80a9 100644 (file)
@@ -17,8 +17,10 @@ import org.aspectj.ajdt.internal.core.builder.AjBuildConfig;
 import org.aspectj.bridge.*;
 import org.aspectj.org.eclipse.jdt.core.compiler.CategorizedProblem;
 import org.aspectj.org.eclipse.jdt.internal.compiler.apt.dispatch.AptProblem;
+import org.aspectj.org.eclipse.jdt.internal.compiler.batch.FileSystem;
 import org.aspectj.org.eclipse.jdt.internal.compiler.batch.Main;
 import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.aspectj.org.eclipse.jdt.internal.compiler.env.IModule;
 import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.aspectj.util.FileUtil;
 import org.aspectj.util.LangUtil;
@@ -162,6 +164,11 @@ public class BuildArgParser extends Main {
                        javaArgList.addAll(parser.getUnparsedArgs());
                        super.configure(javaArgList.toArray(new String[javaArgList.size()]));
 
+                       if (parser.getModuleInfoArgument() != null) {
+                               IModule moduleDesc = super.getModuleDesc(parser.getModuleInfoArgument());
+                               buildConfig.setModuleDesc(moduleDesc);
+                       }
+
                        if (!proceed) {
                                buildConfig.doNotProceed();
                                return buildConfig;
@@ -181,8 +188,14 @@ public class BuildArgParser extends Main {
                        }
 
                        if (setClasspath) {
+                               // This computed classpaths will be missing aspectpaths, inpaths, add those first
                                buildConfig.setClasspath(getClasspath(parser));
+                               buildConfig.setModulepath(getModulepath(parser));
+                               buildConfig.setModulepathClasspathEntries(handleModulepath(parser.modulepath));
+                               buildConfig.setModulesourcepath(getModulesourcepath(parser));
+                               buildConfig.setModulesourcepathClasspathEntries(handleModuleSourcepath(parser.modulesourcepath));
                                buildConfig.setBootclasspath(getBootclasspath(parser));
+                               // TODO other paths (module/module source)
                        }
 
                        if (incrementalMode && (0 == buildConfig.getSourceRoots().size())) {
@@ -214,8 +227,7 @@ public class BuildArgParser extends Main {
                                }
 
                                /* Search aspectpath */
-                               for (Iterator i = buildConfig.getAspectpath().iterator(); i.hasNext();) {
-                                       File pathElement = (File) i.next();
+                               for (File pathElement: buildConfig.getAspectpath()) {
                                        if (!pathElement.isDirectory() && pathElement.equals(outjar)) {
                                                String message = WeaverMessages.format(WeaverMessages.OUTJAR_IN_INPUT_PATH);
                                                MessageUtil.error(handler, message);
@@ -237,6 +249,28 @@ public class BuildArgParser extends Main {
                return buildConfig;
        }
 
+       private void augmentCheckedClasspaths(List<File> extraPathEntries, String encoding) {
+               if (extraPathEntries.size() == 0) {
+                       return;
+               }
+               ArrayList<String> asList = toArrayList(extraPathEntries);
+               List<FileSystem.Classpath> newClasspathEntries = handleClasspath(asList, encoding);
+               FileSystem.Classpath[] newCheckedClasspaths = new FileSystem.Classpath[checkedClasspaths.length + newClasspathEntries.size()];
+               System.arraycopy(checkedClasspaths, 0, newCheckedClasspaths, 0, checkedClasspaths.length);
+               for (int i = 0; i < newClasspathEntries.size();i++) {
+                       newCheckedClasspaths[i + checkedClasspaths.length] = newClasspathEntries.get(i);
+               }
+               checkedClasspaths = newCheckedClasspaths;
+       }
+
+       private ArrayList<String> toArrayList(java.util.List<File> files) {
+               ArrayList<String> arrayList = new ArrayList<String>();
+               for (File file: files) {
+                       arrayList.add(file.getAbsolutePath());
+               }
+               return arrayList;
+       }
+
        public void printVersion() {
                final String version = bind("misc.version", //$NON-NLS-1$
                                new String[] { bind("compiler.name"), //$NON-NLS-1$
@@ -325,7 +359,23 @@ public class BuildArgParser extends Main {
                }
                return ret;
        }
+       
+       public List<String> getModulepath(AjcConfigParser parser) {
+               List<String> ret = new ArrayList<String>();
+               addClasspath(parser.modulepath, ret);
+               return ret;
+       }
 
+       public List<String> getModulesourcepath(AjcConfigParser parser) {
+               List<String> ret = new ArrayList<String>();
+               addClasspath(parser.modulesourcepath, ret);
+               return ret;
+       }
+
+       public ArrayList<FileSystem.Classpath> handleClasspath(ArrayList<String> classpaths, String customEncoding) {
+               return super.handleClasspath(classpaths, customEncoding);
+       }
+       
        /**
         * If the classpath is not set, we use the environment's java.class.path, but remove the aspectjtools.jar entry from that list
         * in order to prevent wierd bootstrap issues (refer to bug#39959).
@@ -380,6 +430,9 @@ public class BuildArgParser extends Main {
        }
 
        private void addClasspath(String classpath, List<String> classpathCollector) {
+               if (classpath == null) {
+                       return;
+               }
                StringTokenizer tokenizer = new StringTokenizer(classpath, File.pathSeparator);
                while (tokenizer.hasMoreTokens()) {
                        classpathCollector.add(tokenizer.nextToken());
@@ -389,10 +442,13 @@ public class BuildArgParser extends Main {
        private class AjcConfigParser extends ConfigParser {
                private String bootclasspath = null;
                private String classpath = null;
+               private String modulepath = null;
+               private String modulesourcepath = null;
                private String extdirs = null;
                private List unparsedArgs = new ArrayList();
                private AjBuildConfig buildConfig;
                private IMessageHandler handler;
+               private String moduleInfoArgument;
 
                public AjcConfigParser(AjBuildConfig buildConfig, IMessageHandler handler) {
                        this.buildConfig = buildConfig;
@@ -402,38 +458,48 @@ public class BuildArgParser extends Main {
                public List getUnparsedArgs() {
                        return unparsedArgs;
                }
+               
+               public String getModuleInfoArgument() {
+                       return this.moduleInfoArgument;
+               }
 
                /**
                 * Extract AspectJ-specific options (except for argfiles). Caller should warn when sourceroots is empty but in incremental
                 * mode. Signals warnings or errors through handler set in constructor.
                 */
-               public void parseOption(String arg, LinkedList args) { // XXX use ListIterator.remove()
+               public void parseOption(String arg, LinkedList<Arg> args) { // XXX use ListIterator.remove()
                        int nextArgIndex = args.indexOf(arg) + 1; // XXX assumes unique
                        // trim arg?
                        buildConfig.setXlazyTjp(true); // now default - MINOR could be pushed down and made default at a lower level
                        if (LangUtil.isEmpty(arg)) {
                                showWarning("empty arg found");
+                       } else if (arg.endsWith("module-info.java")) {
+                               moduleInfoArgument = arg;
                        } else if (arg.equals("-inpath")) {
                                if (args.size() > nextArgIndex) {
                                        // buildConfig.getAjOptions().put(AjCompilerOptions.OPTION_Inpath, CompilerOptions.PRESERVE);
 
-                                       List<File> inPath = buildConfig.getInpath();
                                        StringTokenizer st = new StringTokenizer(((ConfigParser.Arg) args.get(nextArgIndex)).getValue(),
                                                        File.pathSeparator);
+                                       boolean inpathChange = false;
                                        while (st.hasMoreTokens()) {
                                                String filename = st.nextToken();
                                                File file = makeFile(filename);
                                                if (FileUtil.isZipFile(file)) {
-                                                       inPath.add(file);
+                                                       buildConfig.addToInpath(file);
+                                                       inpathChange = true;
                                                } else {
                                                        if (file.isDirectory()) {
-                                                               inPath.add(file);
+                                                               buildConfig.addToInpath(file);
+                                                               inpathChange = true;
                                                        } else {
                                                                showWarning("skipping missing, empty or corrupt inpath entry: " + filename);
                                                        }
                                                }
                                        }
-                                       buildConfig.setInPath(inPath);
+                                       if (inpathChange) {
+                                               buildConfig.processInPath();
+                                       }
                                        args.remove(args.get(nextArgIndex));
                                }
                        } else if (arg.equals("-injars")) {
@@ -467,7 +533,8 @@ public class BuildArgParser extends Main {
                                                String filename = st.nextToken();
                                                File jarFile = makeFile(filename);
                                                if (FileUtil.isZipFile(jarFile) || jarFile.isDirectory()) {
-                                                       buildConfig.getAspectpath().add(jarFile);
+//                                                     buildConfig.getAspectpath().add(jarFile);
+                                                       buildConfig.addToAspectpath(jarFile);
                                                } else {
                                                        showWarning("skipping missing, empty or corrupt aspectpath entry: " + filename);
                                                }
@@ -659,10 +726,47 @@ public class BuildArgParser extends Main {
                                                }
                                        }
                                        classpath = cp.toString();
-                                       args.remove(args.get(nextArgIndex));
+                                       Arg pathArg = args.get(nextArgIndex);
+                                       unparsedArgs.add("-classpath");
+                                       unparsedArgs.add(pathArg.getValue());
+                                       args.remove(pathArg);
                                } else {
                                        showError("-classpath requires classpath entries");
                                }
+                       } else if (arg.equals("--module-path") || arg.equals("-p")) {
+                               if (args.size() > nextArgIndex) {
+                                       String mpArg = ((ConfigParser.Arg) args.get(nextArgIndex)).getValue();
+                                       modulepath = mpArg;
+//                                     StringBuffer mp = new StringBuffer();
+//                                     StringTokenizer strTok = new StringTokenizer(mpArg, File.pathSeparator);
+//                                     while (strTok.hasMoreTokens()) {
+//                                             mp.append(makeFile(strTok.nextToken()));
+//                                             if (strTok.hasMoreTokens()) {
+//                                                     mp.append(File.pathSeparator);
+//                                             }
+//                                     }
+//                                     modulepath = mp.toString();
+                                       args.remove(args.get(nextArgIndex));
+                               } else {
+                                       showError("--module-path requires modulepath entries");
+                               }
+                       } else if (arg.equals("--module-source-path") || arg.equals("-p")) {
+                               if (args.size() > nextArgIndex) {
+                                       String mspArg = ((ConfigParser.Arg) args.get(nextArgIndex)).getValue();
+                                       modulesourcepath = mspArg;
+//                                     StringBuffer mp = new StringBuffer();
+//                                     StringTokenizer strTok = new StringTokenizer(mpArg, File.pathSeparator);
+//                                     while (strTok.hasMoreTokens()) {
+//                                             mp.append(makeFile(strTok.nextToken()));
+//                                             if (strTok.hasMoreTokens()) {
+//                                                     mp.append(File.pathSeparator);
+//                                             }
+//                                     }
+//                                     modulepath = mp.toString();
+                                       args.remove(args.get(nextArgIndex));
+                               } else {
+                                       showError("--module-source-path requires modulepath entries");
+                               }
                        } else if (arg.equals("-extdirs")) {
                                if (args.size() > nextArgIndex) {
                                        String extdirsArg = ((ConfigParser.Arg) args.get(nextArgIndex)).getValue();
index afa936db30b6ff4d552323af237c3add20c0667a..b92a4b43990161c346dc170c01690b08e45bbeba 100644 (file)
@@ -176,7 +176,7 @@ public class ConfigParser {
                }
        }
 
-       protected void parseOption(String arg, LinkedList args) {
+       protected void parseOption(String arg, LinkedList<Arg> args) {
                showWarning("unrecognized option: " + arg);
        }
 
@@ -191,22 +191,22 @@ public class ConfigParser {
                throw new ParseException(CONFIG_MSG + message, location);
        }
 
-       void parseArgs(LinkedList args) {
+       void parseArgs(LinkedList<Arg> args) {
                while (args.size() > 0) {
                        parseOneArg(args);
                }
        }
 
-       protected Arg removeArg(LinkedList args) {
+       protected Arg removeArg(LinkedList<Arg> args) {
                if (args.size() == 0) {
                        showError("value missing");
                        return null;
                } else {
-                       return (Arg) args.removeFirst();
+                       return args.removeFirst();
                }
        }
 
-       protected String removeStringArg(LinkedList args) {
+       protected String removeStringArg(LinkedList<Arg> args) {
                Arg arg = removeArg(args);
                if (arg == null) {
                        return null;
@@ -235,7 +235,7 @@ public class ConfigParser {
                return false;
        }
 
-       void parseOneArg(LinkedList args) {
+       void parseOneArg(LinkedList<Arg> args) {
                Arg arg = removeArg(args);
                String v = arg.getValue();
                location = arg.getLocation();
@@ -245,6 +245,9 @@ public class ConfigParser {
                        parseConfigFileHelper(makeFile(removeArg(args).getValue()));
                } else if (isSourceFileName(v)) {
                        addFileOrPattern(makeFile(v));
+                       if (v.endsWith("module-info.java")) {
+                               parseOption(arg.getValue(), args);                              
+                       }
                } else if (isXml(v)) {
                        addXmlFile(makeFile(v));
                } else {
@@ -284,6 +287,10 @@ public class ConfigParser {
                private Location location;
                private String value;
 
+               public String toString() {
+                       return "Arg[location="+location+" value="+value+"]";
+               }
+               
                public Arg(String value, Location location) {
                        this.value = value;
                        this.location = location;
index 52ad76f5bd68f015c70bbdae463aa731c96358af..935eb3cee48b20ad5a73d9ff9ec3e687b864dbf4 100644 (file)
@@ -107,6 +107,10 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC
                        INameEnvironment nameEnvironment) {
                super(typeRequestor, options, problemReporter, nameEnvironment);
        }
+       
+       public AjLookupEnvironment(LookupEnvironment env, ModuleBinding moduleBinding) {
+               super(env, moduleBinding);
+       }
 
        // ??? duplicates some of super's code
        public void completeTypeBindings() {
@@ -1474,6 +1478,13 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC
     this.factory.cleanup();
     super.reset();
   }
+  
+  @Override
+  public LookupEnvironment wrapInModuleEnvironment(ModuleBinding moduleBinding) {
+         AjLookupEnvironment newAjLookupEnvironment = new AjLookupEnvironment(this, moduleBinding);
+         newAjLookupEnvironment.factory = this.factory;
+         return newAjLookupEnvironment;
+  }
 }
 
 // commented out, supplied as info on how to manipulate annotations in an
index 98bd0484e1b6ad87dad6544fd3aa54a66f77588d..0587c4462ba6fbe8344d7476b944083bc15034df 100644 (file)
@@ -20,14 +20,29 @@ import java.io.File;
 import java.io.FileFilter;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.StringTokenizer;
 
 import org.aspectj.ajdt.ajc.BuildArgParser;
 import org.aspectj.ajdt.internal.compiler.CompilationResultDestinationManager;
+import org.aspectj.org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
+import org.aspectj.org.eclipse.jdt.internal.compiler.batch.ClasspathJar;
+import org.aspectj.org.eclipse.jdt.internal.compiler.batch.ClasspathJrt;
+import org.aspectj.org.eclipse.jdt.internal.compiler.batch.ClasspathLocation;
+import org.aspectj.org.eclipse.jdt.internal.compiler.batch.FileSystem;
+import org.aspectj.org.eclipse.jdt.internal.compiler.batch.Main;
+import org.aspectj.org.eclipse.jdt.internal.compiler.batch.ModuleFinder;
+import org.aspectj.org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath;
+import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.aspectj.org.eclipse.jdt.internal.compiler.env.IModule;
+import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.aspectj.org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.aspectj.org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
 import org.aspectj.util.FileUtil;
 
 /**
@@ -35,7 +50,9 @@ import org.aspectj.util.FileUtil;
  * an AjCompilerOptions instance
  */
 public class AjBuildConfig implements CompilerConfigurationChangeFlags {
-
+       
+       public static final Classpath[] NO_CHECKED_CLASSPATHS = new Classpath[0];
+       
        private boolean shouldProceed = true;
 
        public static final String AJLINT_IGNORE = "ignore";
@@ -59,8 +76,16 @@ public class AjBuildConfig implements CompilerConfigurationChangeFlags {
        private Map<String, File> sourcePathResources = new HashMap<String, File>();
        private List<File> aspectpath = new ArrayList<File>();
        private List<String> classpath = new ArrayList<String>();
+       private List<String> modulepath = new ArrayList<String>();
+       // Expensive to compute (searching modules, parsing module-info)
+       private ArrayList<Classpath> modulepathClasspathEntries = null;
+       private List<String> modulesourcepath = new ArrayList<String>();
+       // Expensive to compute (searching modules, parsing module-info)
+       private ArrayList<Classpath> modulesourcepathClasspathEntries = null;
+       private Classpath[] checkedClasspaths = null;
        private List<String> bootclasspath = new ArrayList<String>();
        private List<String> cpElementsWithModifiedContents = new ArrayList<String>();
+       private IModule moduleDesc;
 
        private File configFile;
        private String lintMode = AJLINT_DEFAULT;
@@ -205,6 +230,53 @@ public class AjBuildConfig implements CompilerConfigurationChangeFlags {
 
        public void setClasspath(List<String> classpath) {
                this.classpath = classpath;
+               checkedClasspaths = null;
+       }
+
+       public List<String> getModulepath() {
+               return modulepath;
+       }
+       
+       public List<String> getModulesourcepath() {
+               return modulesourcepath;
+       }
+
+       public void setModulepath(List<String> modulepath) {
+               this.modulepath = modulepath;
+               checkedClasspaths = null;
+       }
+
+       public void setModulesourcepath(List<String> modulesourcepath) {
+               this.modulesourcepath = modulesourcepath;
+               checkedClasspaths = null;
+       }
+
+       public void setCheckedClasspaths(Classpath[] checkedClasspaths) {
+               this.checkedClasspaths = checkedClasspaths;     
+               checkedClasspaths = null;
+       }
+       
+       private List<Classpath> processFilePath(List<File> path, java.lang.String encoding) {
+               List<Classpath> entries = new ArrayList<Classpath>();
+               for (File file: path) {
+                       entries.add(FileSystem.getClasspath(file.getAbsolutePath(), encoding, null, ClasspathLocation.BINARY));
+               }
+               return entries;
+       }
+
+       private List<Classpath> processStringPath(List<String> path, java.lang.String encoding) {
+               List<Classpath> entries = new ArrayList<Classpath>();
+               for (String file: path) {
+                       entries.add(FileSystem.getClasspath(file, encoding, null, ClasspathLocation.BINARY));
+               }
+               return entries;
+       }
+
+       public Classpath[] getCheckedClasspaths() {
+               if (checkedClasspaths == null) {
+                       computeCheckedClasspath();
+               }
+               return checkedClasspaths;
        }
 
        public List<String> getBootclasspath() {
@@ -225,7 +297,7 @@ public class AjBuildConfig implements CompilerConfigurationChangeFlags {
 
        public List<File> getInpath() {
                // Elements of the list are either archives (jars/zips) or directories
-               return inPath;
+               return Collections.unmodifiableList(inPath);
        }
 
        public List<File> getInJars() {
@@ -246,11 +318,10 @@ public class AjBuildConfig implements CompilerConfigurationChangeFlags {
 
        public void setInJars(List<File> sourceJars) {
                this.inJars = sourceJars;
+               checkedClasspaths = null;
        }
 
-       public void setInPath(List<File> dirsOrJars) {
-               inPath = dirsOrJars;
-
+       public void processInPath() {
                // remember all the class files in directories on the inpath
                binaryFiles = new ArrayList<BinarySourceFile>();
                FileFilter filter = new FileFilter() {
@@ -258,7 +329,7 @@ public class AjBuildConfig implements CompilerConfigurationChangeFlags {
                                return pathname.getPath().endsWith(".class");
                        }
                };
-               for (Iterator<File> iter = dirsOrJars.iterator(); iter.hasNext();) {
+               for (Iterator<File> iter = inPath.iterator(); iter.hasNext();) {
                        File inpathElement = iter.next();
                        if (inpathElement.isDirectory()) {
                                File[] files = FileUtil.listFiles(inpathElement, filter);
@@ -269,6 +340,12 @@ public class AjBuildConfig implements CompilerConfigurationChangeFlags {
                }
        }
 
+       public void setInPath(List<File> dirsOrJars) {
+               inPath = dirsOrJars;
+               checkedClasspaths = null;
+               processInPath();
+       }
+
        public List<File> getSourceRoots() {
                return sourceRoots;
        }
@@ -308,16 +385,18 @@ public class AjBuildConfig implements CompilerConfigurationChangeFlags {
        public List<String> getFullClasspath() {
                List<String> full = new ArrayList<String>();
                full.addAll(getBootclasspath()); // XXX Is it OK that boot classpath overrides inpath/injars/aspectpath?
-               for (Iterator<File> i = inJars.iterator(); i.hasNext();) {
-                       full.add((i.next()).getAbsolutePath());
+               for (File file: inJars) {
+                       full.add(file.getAbsolutePath());
                }
-               for (Iterator<File> i = inPath.iterator(); i.hasNext();) {
-                       full.add((i.next()).getAbsolutePath());
+               for (File file: inPath) {
+                       full.add(file.getAbsolutePath());
                }
-               for (Iterator<File> i = aspectpath.iterator(); i.hasNext();) {
-                       full.add((i.next()).getAbsolutePath());
+               for (File file: aspectpath) {
+                       full.add(file.getAbsolutePath());
                }
                full.addAll(getClasspath());
+               full.addAll(getModulepath());
+               full.addAll(getModulesourcepath());
                // if (null != outputDir) {
                // full.add(outputDir.getAbsolutePath());
                // } else if (null != outputJar) {
@@ -335,11 +414,22 @@ public class AjBuildConfig implements CompilerConfigurationChangeFlags {
        }
 
        public List<File> getAspectpath() {
-               return aspectpath;
+               return Collections.unmodifiableList(aspectpath);
        }
 
        public void setAspectpath(List<File> aspectpath) {
                this.aspectpath = aspectpath;
+               checkedClasspaths = null;
+       }
+       
+       public void addToAspectpath(File file) {
+               this.aspectpath.add(file);
+               checkedClasspaths = null;
+       }
+
+       public void addToInjars(File file) {
+               this.inJars.add(file);
+               checkedClasspaths = null;
        }
 
        /** @return true if any config file, sourceroots, sourcefiles, injars or inpath */
@@ -765,4 +855,116 @@ public class AjBuildConfig implements CompilerConfigurationChangeFlags {
        public void setProjectEncoding(String projectEncoding) {
                options.defaultEncoding = projectEncoding;
        }
+       
+       public String getProjectEncoding() {
+               return options.defaultEncoding;
+       }
+
+       public void setModuleDesc(IModule moduleDesc) {
+               this.moduleDesc = moduleDesc;
+       }
+
+       public IModule getModuleDesc() {
+               return moduleDesc;
+       }
+
+       public void addToInpath(Set<File> newInpathEntries) {
+               if (newInpathEntries != null && newInpathEntries.size() != 0) {
+                       for (File newInpathEntry: newInpathEntries) {
+                               if (!inPath.contains(newInpathEntry)) {
+                                       inPath.add(newInpathEntry);
+                               }
+                       }
+                       checkedClasspaths = null;
+               }
+       }
+
+       public void addToInpath(File newInpathEntry) {
+//             if (!inPath.contains(newInpathEntry)) {
+                       inPath.add(newInpathEntry);
+//             }
+               checkedClasspaths = null;
+       }
+
+       public void addToAspectpath(Set<File> newAspectpathEntries) {
+               if (newAspectpathEntries != null && newAspectpathEntries.size() != 0) {
+                       for (File newAspectpathEntry: newAspectpathEntries) {
+                               if (!aspectpath.contains(newAspectpathEntry)) {
+                                       aspectpath.add(newAspectpathEntry);
+                               }
+                       }
+                       checkedClasspaths = null;
+               }
+       }
+
+       public void setModulepathClasspathEntries(ArrayList<Classpath> modulepathClasspathEntries) {
+               this.modulepathClasspathEntries = modulepathClasspathEntries;
+       }
+
+       public void setModulesourcepathClasspathEntries(ArrayList<Classpath> modulesourcepathClasspathEntries) {
+               this.modulesourcepathClasspathEntries = modulesourcepathClasspathEntries;
+       }
+
+       public File removeAspectPathEntry(int i) {
+               checkedClasspaths = null;
+               return aspectpath.remove(i);
+       }
+
+       public String removeClasspathEntry(int i) {
+               checkedClasspaths = null;
+               return classpath.remove(i);
+       }
+
+       public File removeInpathEntry(int i) {
+               checkedClasspaths = null;
+               return inPath.remove(i);
+       }
+
+       public File removeInjarsEntry(int i) {
+               checkedClasspaths = null;
+               return inJars.remove(0);
+       }
+
+
+       // This is similar to the calculation done in Main.setPaths() but it isn't as sophisticated
+       // as that one (doesn't need to be) and it also considers the additional paths for an 
+       // AspectJ project (aspectpath/inpath/injars)
+       private void computeCheckedClasspath() {                
+               // Follow what we do in getFullClasspath():
+               // bootclasspath, injars, inpath, aspectpath, classpath, modulepath
+
+               String encoding = getProjectEncoding();
+               // What to do about bootclasspath on java 9?
+               
+               // ArrayList<Classpath> allPaths = handleBootclasspath(bootclasspaths, customEncoding);
+               ArrayList<FileSystem.Classpath> allPaths = new ArrayList<FileSystem.Classpath>(); 
+               allPaths.addAll(processStringPath(bootclasspath, encoding));
+               allPaths.addAll(processFilePath(inJars, encoding));
+               allPaths.addAll(processFilePath(inPath, encoding)); 
+               allPaths.addAll(processFilePath(aspectpath, encoding)); 
+               if (modulepathClasspathEntries != null) {
+                       allPaths.addAll(modulepathClasspathEntries);
+               }
+               if (modulesourcepathClasspathEntries != null) {
+                       allPaths.addAll(modulesourcepathClasspathEntries);
+               }
+               // The classpath is done after modules to give precedence to modules that share the
+               // same paths as classpath elements (the upcoming normalize will remove later dups)
+               allPaths.addAll(processStringPath(classpath, encoding));
+               for (Iterator<FileSystem.Classpath> iter = allPaths.iterator();iter.hasNext();) {
+                       Classpath next = iter.next();
+                       if (next == null) {
+                               iter.remove();
+                       }
+               }
+               allPaths = FileSystem.ClasspathNormalizer.normalize(allPaths);
+               this.checkedClasspaths = new FileSystem.Classpath[allPaths.size()];
+               allPaths.toArray(this.checkedClasspaths);
+               for (int i=0;i<checkedClasspaths.length;i++) {
+                       if (checkedClasspaths[i] == null) {
+                               throw new IllegalStateException();
+                       }
+               }
+       }
+       
 }
index 164af662982b8809251b326a04a46a7dbb8b6af4..85b665dcdf743c62821e18a165ddbf7012778400 100644 (file)
@@ -79,6 +79,7 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.batch.ClasspathLocation;
 import org.aspectj.org.eclipse.jdt.internal.compiler.batch.CompilationUnit;
 import org.aspectj.org.eclipse.jdt.internal.compiler.batch.FileSystem;
 import org.aspectj.org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.aspectj.org.eclipse.jdt.internal.compiler.env.IModule;
 import org.aspectj.org.eclipse.jdt.internal.compiler.env.INameEnvironment;
 import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.aspectj.org.eclipse.jdt.internal.compiler.parser.Parser;
@@ -865,8 +866,7 @@ public class AjBuildManager implements IOutputClassFileNameProvider, IBinarySour
                        bcelWorld.getLint().setFromProperties(buildConfig.getLintSpecFile());
                }
 
-               for (Iterator i = buildConfig.getAspectpath().iterator(); i.hasNext();) {
-                       File f = (File) i.next();
+               for (File f: buildConfig.getAspectpath()) {
                        if (!f.exists()) {
                                IMessage message = new Message("invalid aspectpath entry: " + f.getName(), null, true);
                                handler.handleMessage(message);
@@ -943,7 +943,19 @@ public class AjBuildManager implements IOutputClassFileNameProvider, IBinarySour
                // a classpathDirectory object that will attempt to look for source when it can't find binary.
                // int[] classpathModes = new int[classpaths.length];
                // for (int i =0 ;i<classpaths.length;i++) classpathModes[i]=ClasspathDirectory.BINARY;
-               return new FileSystem(classpaths, filenames, defaultEncoding, ClasspathLocation.BINARY);
+               
+               FileSystem nameEnvironment = null;
+               // TODO J9 The compiler likes to work in terms of checked classpath objects - these will be different
+               // depending on where the code came from (classpath, modulepath). If working with just the raw
+               // 'classpaths' object it isn't recording where the code came from. This will be an issue later for
+               // weaving, the distinction will need to be maintained for proper 'module aware/respecting' weaving.
+               if (buildConfig.getCheckedClasspaths() == null) {
+                       nameEnvironment = new FileSystem(classpaths, filenames, defaultEncoding, ClasspathLocation.BINARY);
+               } else {
+                       nameEnvironment = new FileSystem(buildConfig.getCheckedClasspaths(), filenames, false);
+               }
+               nameEnvironment.module = buildConfig.getModuleDesc();
+               return nameEnvironment;
        }
 
        public IProblemFactory getProblemFactory() {
@@ -962,9 +974,30 @@ public class AjBuildManager implements IOutputClassFileNameProvider, IBinarySour
                if ("".equals(defaultEncoding)) {//$NON-NLS-1$
                        defaultEncoding = null;
                }
-
+               CompilationUnit moduleCU = null;
+               
+               // TODO building with multiple module-infos?
+               int moduleIndex = -1;
+               IModule moduleDesc = buildConfig.getModuleDesc();
+               String moduleName = moduleDesc == null? null: new String(moduleDesc.name());
+               for (int i=0;i<fileCount;i++) {
+                       if (filenames[i].endsWith("module-info.java")) {
+                               moduleIndex = i;
+                               moduleCU = new CompilationUnit(null, filenames[i], defaultEncoding, null, false, moduleName);
+                       }
+               }
+               
                for (int i = 0; i < fileCount; i++) {
-                       units[i] = new CompilationUnit(null, filenames[i], defaultEncoding);
+//                     units[i] = new CompilationUnit(null, filenames[i], defaultEncoding);
+                       if (i == moduleIndex) {
+                               units[i] = moduleCU;
+                       } else {
+                               units[i] = new CompilationUnit(null, filenames[i], defaultEncoding, null, false, moduleName);
+                               units[i].setModule(moduleCU);
+                       }
+//                     new CompilationUnit(null, fileName, encoding, this.destinationPaths[i],
+//                                     shouldIgnoreOptionalProblems(this.ignoreOptionalProblemsFromFolders, fileName.toCharArray()), 
+//                                     this.modNames[i]);
                }
                return units;
        }
index 71c3041e841f536dd5669d18555c3599a3bd08be..b3cb0e2d1be2157aa56bf7b4bf2ba39ba79eda54 100644 (file)
@@ -26,18 +26,18 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
 import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
 import org.aspectj.org.eclipse.jdt.internal.compiler.env.IBinaryType;
 import org.aspectj.org.eclipse.jdt.internal.compiler.env.IModule;
-import org.aspectj.org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+import org.aspectj.org.eclipse.jdt.internal.compiler.env.IModuleAwareNameEnvironment;
 import org.aspectj.org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
 import org.aspectj.util.FileUtil;
 
-public class StatefulNameEnvironment implements INameEnvironment {
+public class StatefulNameEnvironment implements IModuleAwareNameEnvironment {
        private Map<String,File> classesFromName;
        private Map<String,NameEnvironmentAnswer> inflatedClassFilesCache;
        private Set<String> packageNames;
        private AjState state;
-       private INameEnvironment baseEnvironment;
+       private IModuleAwareNameEnvironment baseEnvironment;
 
-       public StatefulNameEnvironment(INameEnvironment baseEnvironment, Map<String,File> classesFromName, AjState state) {
+       public StatefulNameEnvironment(IModuleAwareNameEnvironment baseEnvironment, Map<String,File> classesFromName, AjState state) {
                this.classesFromName = classesFromName;
                this.inflatedClassFilesCache = new HashMap<String,NameEnvironmentAnswer>();
                this.baseEnvironment = baseEnvironment;
@@ -130,4 +130,34 @@ public class StatefulNameEnvironment implements INameEnvironment {
                this.classesFromName = classNameToFileMap;
        }
 
+       @Override
+       public NameEnvironmentAnswer findType(char[][] compoundName, char[] moduleName) {
+               return baseEnvironment.findType(compoundName, moduleName);
+       }
+
+       @Override
+       public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName, char[] moduleName) {
+               return baseEnvironment.findType(typeName, packageName, moduleName);
+       }
+
+       @Override
+       public char[][] getModulesDeclaringPackage(char[][] parentPackageName, char[] name, char[] moduleName) {
+               return baseEnvironment.getModulesDeclaringPackage(parentPackageName, name, moduleName);
+       }
+
+       @Override
+       public boolean hasCompilationUnit(char[][] qualifiedPackageName, char[] moduleName, boolean checkCUs) {
+               return baseEnvironment.hasCompilationUnit(qualifiedPackageName, moduleName, checkCUs);
+       }
+
+       @Override
+       public IModule getModule(char[] moduleName) {
+               return baseEnvironment.getModule(moduleName);
+       }
+
+       @Override
+       public char[][] getAllAutomaticModules() {
+               return baseEnvironment.getAllAutomaticModules();
+       }
+
 }
index 3799b4cdab4cf96ecdd805d2e66fbeb619a733bb..c4be2693607cf37b958fc3d662446cc3267016bc 100644 (file)
@@ -57,10 +57,10 @@ public class AjBuildManagerTest extends TestCase {
        }
 
        public void testSimpleStructure() throws IOException /* , CoreException */{
-
                AjBuildManager manager = new AjBuildManager(messageWriter);
                BuildArgParser parser = new BuildArgParser(messageWriter);
                String javaClassPath = System.getProperty("java.class.path");
+               System.out.println(javaClassPath);
                String sandboxName = Ajc.createEmptySandbox().getAbsolutePath();
                AjBuildConfig buildConfig = parser.genBuildConfig(new String[] { "-d", sandboxName, "-classpath", javaClassPath,
                                AjdtAjcTests.TESTDATA_PATH + "/src1/A.java",
index 1693178e39e7cc2396f5a27bd24142080434338d..101fdade1fd6a28aa455f41d212685a7fd92f619 100644 (file)
@@ -48,44 +48,48 @@ public class AjStateTest extends TestCase {
        }
 
        public void testAddEntryToAspectpath() {
-               newConfig.getAspectpath().add(new File("anotherEntry.jar"));
+               newConfig.addToAspectpath(new File("anotherEntry.jar"));
+//             newConfig.getAspectpath().add(new File("anotherEntry.jar"));
                assertFalse("Can do incremental", aRightState.prepareForNextBuild(newConfig));
        }
 
        public void testRemoveEntryFromAspectpath() {
-               newConfig.getAspectpath().remove(0);
+               newConfig.removeAspectPathEntry(0);
                assertFalse("Can do incremental", aRightState.prepareForNextBuild(newConfig));
        }
 
        public void testReorderAspectpath() {
-               String o = newConfig.getClasspath().remove(0);
-               newConfig.getAspectpath().add(new File(o));
+               String o = newConfig.removeClasspathEntry(0);
+               newConfig.addToAspectpath(new File(o));
+//             newConfig.getAspectpath().add(new File(o));
                assertFalse("Can do incremental", aRightState.prepareForNextBuild(newConfig));
        }
 
        public void testAddEntryToInpath() {
-               newConfig.getInpath().add(new File("anotherEntry"));
+               newConfig.addToInpath(new File("anotherEntry"));
                assertFalse("Can do incremental", aRightState.prepareForNextBuild(newConfig));
        }
 
        public void testRemoveEntryFromInpath() {
-               newConfig.getInpath().remove(0);
+               newConfig.removeInpathEntry(0);//getInpath().remove(0);
                assertFalse("Can do incremental", aRightState.prepareForNextBuild(newConfig));
        }
 
        public void testReorderInpath() {
-               String o = newConfig.getClasspath().remove(0);
-               newConfig.getInpath().add(new File(o));
+               String o = newConfig.removeClasspathEntry(0);//getClasspath().remove(0);
+               newConfig.addToInpath(new File(o));//getInpath().add(new File(o));
                assertFalse("Can do incremental", aRightState.prepareForNextBuild(newConfig));
        }
 
        public void testAddEntryToInjars() {
-               newConfig.getInJars().add(new File("anotherEntry.jar"));
+               newConfig.addToInjars(new File("anotherEntry.jar"));
+//             newConfig.getInJars().add(new File("anotherEntry.jar"));
                assertFalse("Can do incremental", aRightState.prepareForNextBuild(newConfig));
        }
 
        public void testRemoveEntryFromInjars() {
-               newConfig.getInJars().remove(0);
+               newConfig.removeInjarsEntry(0);
+//             newConfig.getInJars().remove(0);
                assertFalse("Can do incremental", aRightState.prepareForNextBuild(newConfig));
        }
 
index 12b1e3508979eb906661374bc9e2bd6b934fe326..b665afeba1474539837515fe777aa46e5d51325c 100644 (file)
@@ -581,7 +581,7 @@ public class AjcTestCase extends TestCase {
        }
 
        public RunResult run(String className, String[] args, String classpath) {
-               return run(className, args, "", null, false,false);
+               return run(className, null, args, "", "", null, false,false);
        }
 
        /**
@@ -593,7 +593,7 @@ public class AjcTestCase extends TestCase {
         *        be appended to the classpath, as will any jars in the sandbox.
         * @param runSpec 
         */
-       public RunResult run(String className, String[] args, String vmargs, final String classpath, boolean useLTW, boolean useFullLTW) {
+       public RunResult run(String className, String moduleName, String[] args, String vmargs, final String classpath, String modulepath, boolean useLTW, boolean useFullLTW) {
 
                if (args != null) {
                        for (int i = 0; i < args.length; i++) {
@@ -607,8 +607,16 @@ public class AjcTestCase extends TestCase {
                        cp.append(substituteSandbox(classpath));
                        cp.append(File.pathSeparator);
                }
-               cp.append(ajc.getSandboxDirectory().getAbsolutePath());
-               getAnyJars(ajc.getSandboxDirectory(), cp);
+               if (moduleName == null) {
+                       // When running modules, we want more control so don't try to be helpful by adding all jars
+                       cp.append(ajc.getSandboxDirectory().getAbsolutePath());
+                       getAnyJars(ajc.getSandboxDirectory(), cp);
+               }
+               StringBuffer mp = new StringBuffer();
+               if (modulepath != null) {
+                       mp.append(substituteSandbox(modulepath));
+                       mp.append(File.pathSeparator);
+               }
 
                URLClassLoader sandboxLoader;
                ClassLoader parentLoader = getClass().getClassLoader().getParent();
@@ -639,7 +647,6 @@ public class AjcTestCase extends TestCase {
                        String absPath = directory.getAbsolutePath();
                        String javaagent= absPath+File.separator+".."+File.separator+"aj-build"+File.separator+"dist"+File.separator+"tools"+File.separator+"lib"+File.separator+"aspectjweaver.jar";
                        try {
-
                                String command ="java " +vmargs+ " -classpath " + cp +" -javaagent:"+javaagent + " " + className ;
                                
                                // Command is executed using ProcessBuilder to allow setting CWD for ajc sandbox compliance
@@ -654,10 +661,35 @@ public class AjcTestCase extends TestCase {
                                System.out.println("Error executing full LTW test: " + e);
                                e.printStackTrace();
                        }
-
                        return lastRunResult;
-               
-               }else{
+               } else if (moduleName != null) {
+                       // CODE FOR RUNNING MODULES
+                       if(vmargs == null){
+                               vmargs ="";
+                       }
+                       try {
+                               if (mp.indexOf("$runtime") != -1) {
+                                       mp = mp.replace(mp.indexOf("$runtime"),"$runtime".length(),TestUtil.aspectjrtPath().toString());
+                               }
+                               if (cp.indexOf("aspectjrt")==-1) {
+                                       cp.append(TestUtil.aspectjrtPath().getPath()).append(File.pathSeparator);
+                               }
+                               String command = LangUtil.getJavaExecutable().getAbsolutePath() + " " +vmargs+ (cp.length()==0?"":" -classpath " + cp) + " -p "+mp+" --module "+moduleName   ;
+                               System.out.println("Command is "+command);
+                               // Command is executed using ProcessBuilder to allow setting CWD for ajc sandbox compliance
+                               ProcessBuilder pb = new ProcessBuilder(tokenizeCommand(command));
+                               pb.directory( new File(ajc.getSandboxDirectory().getAbsolutePath()));
+                               exec = pb.start();
+                       BufferedReader stdInput = new BufferedReader(new InputStreamReader(exec.getInputStream()));
+                       BufferedReader stdError = new BufferedReader(new InputStreamReader(exec.getErrorStream()));
+                               exec.waitFor();
+                               lastRunResult = createResultFromBufferReaders(command,stdInput, stdError); 
+                       } catch (Exception e) {
+                               System.out.println("Error executing module test: " + e);
+                               e.printStackTrace();
+                       }
+                       return lastRunResult;
+               } else {
                        cp.append(DEFAULT_CLASSPATH_ENTRIES);
                        URL[] urls = getURLs(cp.toString());
                        sandboxLoader = new URLClassLoader(urls, parentLoader);
@@ -666,7 +698,8 @@ public class AjcTestCase extends TestCase {
                ByteArrayOutputStream baosErr = new ByteArrayOutputStream();
                
 
-               StringBuffer command = new StringBuffer("java -classpath ");
+               StringBuffer command = new StringBuffer();
+               command.append("java -classpath ");
                command.append(cp.toString());
                command.append(" ");
                command.append(className);
@@ -834,15 +867,15 @@ public class AjcTestCase extends TestCase {
                return urls;
        }
 
-       private String substituteSandbox(String classpath) {
-               // the longhand form of the non 1.3 API: classpath.replace("$sandbox", ajc.getSandboxDirectory().getAbsolutePath());
-               while (classpath.indexOf("$sandbox") != -1) {
-                       int pos = classpath.indexOf("$sandbox");
-                       String firstbit = classpath.substring(0, pos);
-                       String endbit = classpath.substring(pos + 8);
-                       classpath = firstbit + ajc.getSandboxDirectory().getAbsolutePath() + endbit;
+       private String substituteSandbox(String path) {
+               // the longhand form of the non 1.3 API: path.replace("$sandbox", ajc.getSandboxDirectory().getAbsolutePath());
+               while (path.indexOf("$sandbox") != -1) {
+                       int pos = path.indexOf("$sandbox");
+                       String firstbit = path.substring(0, pos);
+                       String endbit = path.substring(pos + 8);
+                       path = firstbit + ajc.getSandboxDirectory().getAbsolutePath() + endbit;
                }
-               return classpath;
+               return path;
        }
 
        /**
@@ -864,6 +897,8 @@ public class AjcTestCase extends TestCase {
                         args[i + 1] = substituteSandbox(args[i + 1]);
                         String next = args[i + 1];
                         hasruntime = ((null != next) && (-1 != next.indexOf("aspectjrt.jar")));
+                } else if ("-p".equals(args[i]) || "--module-path".equals(args[i])) {
+                    args[i + 1] = substituteSandbox(args[i + 1]);
                 }
         }
         if (-1 == cpIndex) {
index f7971bddb793f423d399a34193797519b9c70610..94ae83441f5ca99e6d5d8b66f53eaf4f9a3fd920 100644 (file)
@@ -12,7 +12,7 @@ import java.util.*;
 
 public class SoftHashMap<K,V> extends AbstractMap<K,V> {
        private Map<K, SpecialValue> map;
-       private ReferenceQueue<? super V> rq = new ReferenceQueue<>();
+       private ReferenceQueue<? super V> rq = new ReferenceQueue();
 
        public SoftHashMap() {
                this.map = new HashMap<K,SpecialValue>();