]> source.dussan.org Git - aspectj.git/commitdiff
Final bits of AspectJ 1.9.4
authorAndy Clement <aclement@pivotal.io>
Fri, 10 May 2019 15:39:28 +0000 (08:39 -0700)
committerAndy Clement <aclement@pivotal.io>
Fri, 10 May 2019 15:39:28 +0000 (08:39 -0700)
docs/dist/doc/README-194.html [new file with mode: 0644]
docs/dist/doc/index.html
org.aspectj.lib/pom.xml
org.eclipse.jdt.core/pom.xml
pom.xml
weaver/src/main/java/org/aspectj/weaver/bcel/ClassPathManager.java
weaver/src/test/java/org/aspectj/weaver/bcel/ClasspathManagerTestCase.java [new file with mode: 0644]
weaver/src/test/java/org/aspectj/weaver/bcel/JImageTestCase.java

diff --git a/docs/dist/doc/README-194.html b/docs/dist/doc/README-194.html
new file mode 100644 (file)
index 0000000..c133073
--- /dev/null
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html> <head>
+<title>AspectJ 1.9.4 Readme</title>
+<style type="text/css">
+<!--
+  P   { margin-left:  20px; }
+  PRE { margin-left:  20px; }
+  LI  { margin-left:  20px; }
+  H4  { margin-left:  20px; }
+  H3  { margin-left:  10px; }
+-->
+</style>
+</head>
+
+<body>
+<div align="right"><small>
+&copy; Copyright 2019 Contributors.
+All rights reserved.
+</small></div>
+<p>The full list of resolved issues in 1.9.4 is available 
+<a href="https://bugs.eclipse.org/bugs/buglist.cgi?bug_status=RESOLVED&bug_status=VERIFIED&bug_status=CLOSED&f0=OP&f1=OP&f3=CP&f4=CP&j1=OR&list_id=16866879&product=AspectJ&query_format=advanced&target_milestone=1.9.4">here</a></h2>.</p>
+
+<p>AspectJ 1.9.4 has a couple of important fixes in it:
+<ul>
+<li>Due to the new maven build process being used to build release artifacts
+for the first time, there were errors in the aspectjweaver jar that affected
+the ability to use it on the command line as an agent,
+this is now fixed.
+<li>A number of users were noticing a ClassCastException problem, which I believe was due to trying to
+run AspectJ on one level of the JDK whilst targeting another. This can happen quite easily in eclipse
+if running your Eclipse on Java 8 but developing projects targeting Java 11.
+The class cast is because Java8 couldn't understand
+the packaging of system classes post Java9 and so couldn't find java.lang.Object. This has now all been
+tidied up and should work much better. More details in <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=546807">546807</a>,
+thanks to Denys Khanzhyiev for some tips on getting to the right solution.
+</ul>
+
+
+<p>Available: 1.9.4 available 10-May-2019</p>
+
+<br><br>
+
+
+<!-- ============================== -->  
+</body>
+</html>
index 5d6805af5db250096c618c85c86f0f3e7117c2fa..68abf89d30e37309e6de8046631d166e1e5bd7ef 100644 (file)
 <tr> <td>README's
      </td>
      <td>Changes and porting guide for AspectJ 
+        <a href="README-194.html">1.9.4</a>,
         <a href="README-193.html">1.9.3</a>,
         <a href="README-192.html">1.9.2</a>,
         <a href="README-191.html">1.9.1</a>,
index d90092aab9154a43791d6e40913d2b108102dea5..3e60912994ba7c578f524266a377e5d913aed862 100644 (file)
@@ -6,7 +6,7 @@
   <parent>
     <groupId>org.aspectj</groupId>
     <artifactId>aspectj-parent</artifactId>
-    <version>1.9.3.BUILD-SNAPSHOT</version>
+    <version>1.9.4.BUILD-SNAPSHOT</version>
     <relativePath>..</relativePath>
   </parent>
 
index de9dcdd85c7c3bd3c3191682215fc5ee89025206..a0ad386f3f5ae01405ab4c7b7359a7ff2fd3a931 100644 (file)
@@ -33,7 +33,7 @@
                         <configuration>
                             <groupId>org.aspectj</groupId>
                             <artifactId>org.eclipse.jdt.core</artifactId>
-                            <version>1.9.3.BUILD-SNAPSHOT</version>
+                            <version>1.9.4.BUILD-SNAPSHOT</version>
                             <packaging>jar</packaging>
                             <file>${basedir}/jdtcore-for-aspectj.jar</file>
                             <createChecksum>true</createChecksum>
@@ -49,7 +49,7 @@
                         <configuration>
                             <groupId>org.aspectj</groupId>
                             <artifactId>org.eclipse.jdt.core</artifactId>
-                            <version>1.9.3.BUILD-SNAPSHOT</version>
+                            <version>1.9.4.BUILD-SNAPSHOT</version>
                             <packaging>jar</packaging>
                             <file>${basedir}/jdtcore-for-aspectj-src.zip</file>
                             <createChecksum>true</createChecksum>
diff --git a/pom.xml b/pom.xml
index 15f944cc88b93e3d539d906ac8972ebc8d6745bb..7f8492b4e7ed9d6276a8c13d40c0e07fdcaf1b15 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
        <modelVersion>4.0.0</modelVersion>
 
        <properties>
-               <revision>1.9.3.BUILD-SNAPSHOT</revision>
+               <revision>1.9.4.BUILD-SNAPSHOT</revision>
                <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
 
index d617bbfa3a366ec6a272dbd9d65267bc5f46a147..b903ee6de77c5ba6ce3660840752cf436b7b1773 100644 (file)
@@ -17,7 +17,10 @@ import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.MalformedURLException;
 import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
 import java.nio.file.FileSystem;
 import java.nio.file.FileSystems;
 import java.nio.file.FileVisitResult;
@@ -105,9 +108,9 @@ public class ClassPathManager {
                                return;
                        }
                        try {
-                               if (lc.endsWith(LangUtil.JRT_FS)) { // Java9
-                                       if (LangUtil.is19VMOrGreater()) {
-                                               entries.add(new JImageEntry());
+                               if (lc.endsWith(LangUtil.JRT_FS)) { // Java9+
+                                       if (LangUtil.is18VMOrGreater()) {
+                                               entries.add(new JImageEntry(lc));
                                        }
                                } else {
                                        entries.add(new ZipFileEntry(f));
@@ -316,24 +319,59 @@ public class ClassPathManager {
         * helps reduce memory usage but still gives reasonably fast lookup performance.
         */
        static class JImageEntry extends Entry {
+                               
+               // Map from a JRT-FS file to the cache state for that file
+               private static Map<String, JImageState> states = new HashMap<>();
                
-               private static FileSystem fs = null;
+               private JImageState state;
                
-               private final static Map<String, Path> fileCache = new SoftHashMap<String, Path>();
-
-               private final static Map<String, Path> packageCache = new HashMap<String, Path>();
-               
-               private static boolean packageCacheInitialized = false;
+               // TODO memory management here - is it held onto too long when LTW?
+               static class JImageState {
+                       private final String jrtFsPath;
+                       private final FileSystem fs;
+                       Map<String,Path> fileCache = new SoftHashMap<String, Path>();
+                       boolean packageCacheInitialized = false;
+                       Map<String,Path> packageCache = new HashMap<String, Path>();
+                       
+                       public JImageState(String jrtFsPath, FileSystem fs) {
+                               this.jrtFsPath = jrtFsPath;
+                               this.fs = fs;
+                       }
+               }
 
-               public JImageEntry() {
-                       if (fs == null) {
-                               try {
-                                       fs = FileSystems.getFileSystem(JRT_URI);
-                               } catch (Throwable t) {
-                                       throw new IllegalStateException("Unexpectedly unable to initialize a JRT filesystem", t);
+               public JImageEntry(String jrtFsPath) {
+                       state = states.get(jrtFsPath);
+                       if (state == null) {
+                               synchronized (states) {
+                                       if (state == null) {
+                                               URL jrtPath = null;
+                                               try {
+                                                       jrtPath = new File(jrtFsPath).toPath().toUri().toURL();
+                                               } catch (MalformedURLException e) {
+                                                       System.out.println("Unexpected problem processing "+jrtFsPath+" bad classpath entry? skipping:"+e.getMessage());
+                                                       return;
+                                               }
+                                               String jdkHome = new File(jrtFsPath).getParentFile().getParent();
+                                               FileSystem fs = null;
+                                               try {
+                                                       if (LangUtil.is19VMOrGreater()) {
+                                                               HashMap<String, String> env = new HashMap<>();
+                                                               env.put("java.home",  jdkHome);
+                                                               fs = FileSystems.newFileSystem(JRT_URI, env);
+                                                       } else {
+                                                               URLClassLoader loader = new URLClassLoader(new URL[] { jrtPath });
+                                                               HashMap<String, ?> env = new HashMap<>();
+                                                               fs = FileSystems.newFileSystem(JRT_URI, env, loader);
+                                                       }
+                                                       state = new JImageState(jrtFsPath, fs);
+                                                       states.put(jrtFsPath, state);
+                                                       buildPackageMap();
+                                               } catch (Throwable t) {
+                                                       throw new IllegalStateException("Unexpectedly unable to initialize a JRT filesystem", t);
+                                               }
+                                       }
                                }
                        }
-                       buildPackageMap();
                }
                
                class PackageCacheBuilderVisitor extends SimpleFileVisitor<Path> {
@@ -344,7 +382,7 @@ public class ClassPathManager {
                                        if (fnc > 3) { // There is a package name - e.g. /modules/java.base/java/lang/Object.class
                                                Path packagePath = file.subpath(2, fnc-1); // e.g. java/lang
                                                String packagePathString = packagePath.toString();
-                                               packageCache.put(packagePathString, file.subpath(0, fnc-1)); // java/lang -> /modules/java.base/java/lang
+                                               state.packageCache.put(packagePathString, file.subpath(0, fnc-1)); // java/lang -> /modules/java.base/java/lang
                                        }
                                }
                                return FileVisitResult.CONTINUE;
@@ -355,9 +393,9 @@ public class ClassPathManager {
                 * Create a map from package names to the specific directory of the package members in the filesystem.
                 */
                private synchronized void buildPackageMap() {
-                       if (!packageCacheInitialized) {
-                               packageCacheInitialized = true;
-                               Iterable<java.nio.file.Path> roots = fs.getRootDirectories();
+                       if (!state.packageCacheInitialized) {
+                               state.packageCacheInitialized = true;
+                               Iterable<java.nio.file.Path> roots = state.fs.getRootDirectories();
                                PackageCacheBuilderVisitor visitor = new PackageCacheBuilderVisitor();
                                try {
                                        for (java.nio.file.Path path : roots) {
@@ -392,7 +430,7 @@ public class ClassPathManager {
                                        Path filePath = file.subpath(2, fnc);
                                        String filePathString = filePath.toString();
                                        if (filePathString.equals(name)) {
-                                               fileCache.put(filePathString, file);
+                                               state.fileCache.put(filePathString, file);
                                                found = file;
                                                return FileVisitResult.TERMINATE;
                                        }
@@ -414,7 +452,7 @@ public class ClassPathManager {
                @Override
                public ClassFile find(String name) throws IOException {
                        String fileName = name.replace('.', '/') + ".class";
-                       Path file = fileCache.get(fileName);
+                       Path file = state.fileCache.get(fileName);
                        if (file == null) {
                                // Check the packages map to see if we know about this package
                                int idx = fileName.lastIndexOf('/');
@@ -426,7 +464,7 @@ public class ClassPathManager {
                                String packageName = null;
                                if (idx !=-1 ) {
                                        packageName = fileName.substring(0, idx);
-                                       packageStart = packageCache.get(packageName);
+                                       packageStart = state.packageCache.get(packageName);
                                        if (packageStart != null) {
                                                file = searchForFileAndCache(packageStart, fileName);
                                        }
@@ -440,12 +478,12 @@ public class ClassPathManager {
                        return cf;
                }
 
-               static Map<String, Path> getPackageCache() {
-                       return packageCache;
+               Map<String, Path> getPackageCache() {
+                       return state.packageCache;
                }
                
-               static Map<String, Path> getFileCache() {
-                       return fileCache;
+               Map<String, Path> getFileCache() {
+                       return state.fileCache;
                }
 
        }
diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/ClasspathManagerTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/ClasspathManagerTestCase.java
new file mode 100644 (file)
index 0000000..f4f84f1
--- /dev/null
@@ -0,0 +1,214 @@
+/* *******************************************************************
+ * Copyright (c) 2019 Contributors
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ * ******************************************************************/
+package org.aspectj.weaver.bcel;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.aspectj.apache.bcel.classfile.ClassFormatException;
+import org.aspectj.apache.bcel.classfile.ClassParser;
+import org.aspectj.apache.bcel.classfile.JavaClass;
+import org.aspectj.bridge.AbortException;
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.IMessage.Kind;
+import org.aspectj.bridge.IMessageHandler;
+import org.aspectj.util.LangUtil;
+import org.aspectj.weaver.UnresolvedType;
+import org.aspectj.weaver.bcel.ClassPathManager.ClassFile;
+
+import junit.framework.TestCase;
+
+/**
+ * Should run these tests 3 times on each JDK level (8, 9, 11). On each one 3 of the
+ * tests should pass indicating that JDK can successfully access system types in 
+ * each JDK level.
+ * 
+ * @author Andy Clement
+ */
+public class ClasspathManagerTestCase extends TestCase {
+       
+       // Works on my machine where all jvms under ~/jvms
+       private static String java18_rtjar = findJvm("j.*18.*","rt.jar");
+       private static String java9_jrtfsjar = findJvm("j.*9.*","jrt-fs.jar");;
+       private static String java11_jrtfsjar = findJvm("j.*11.*","jrt-fs.jar");;
+       
+       private static String findJvm(String pattern, String jar) {
+               String start = System.getProperty("user.home")+"/jvms";
+               for (File f: new File(start).listFiles()) {
+                       if (f.isDirectory() && Pattern.matches(pattern, f.getName())) {
+                               File result = walk(f, jar);
+                               if (result !=null) {
+                                       System.out.println("For "+pattern+" found "+result.getAbsolutePath());
+                                       return result.getAbsolutePath();
+                               }
+                       }
+               }
+               return null;
+       }
+       
+       private static File walk(File dir, String jar) {
+               File[] fs = dir.listFiles();
+               if (fs!=null) {
+                       for (File f: fs) {
+                               if (f.getName().equals(jar)) {
+                                       return f;
+                               } else if (f.isDirectory()) {
+                                       File s = walk(f, jar);
+                                       if (s!=null) {
+                                               return s;
+                                       }
+                               }
+                       }
+               }
+               return null;
+       }
+       
+       public void testInstructions() {
+               System.out.println("This test is really only for standalone usage as it need executing on multiple JDK levels");
+       }
+
+       public void xtestSanity18accessing18RTJAR() throws IOException {
+       if (LangUtil.getVmVersion()>8) fail("Must be Java 8");
+       List<String> classpath = new ArrayList<>();
+       classpath.add(java18_rtjar);
+       ClassPathManager cpm = new ClassPathManager(classpath, new MH());
+       ClassFile t = cpm.find(UnresolvedType.forSignature("Ljava/lang/Object;"));
+       assertNotNull(t);       
+    }
+    
+    public void xtestJava18accessing11JRT() throws ClassFormatException, IOException {
+       if (LangUtil.getVmVersion()>8) fail("Must be Java 8");
+       List<String> classpath = new ArrayList<>();
+       classpath.add(java11_jrtfsjar);
+       ClassPathManager cpm = new ClassPathManager(classpath, new MH());
+       ClassFile t = cpm.find(UnresolvedType.forSignature("Ljava/lang/String;"));
+       assertNotNull(t);
+       ClassParser classParser = new ClassParser(t.getInputStream(),t.getPath());
+       JavaClass clazz = classParser.parse();
+       // isBlank() exists on Java 11
+       long c = Arrays.asList(clazz.getMethods()).stream().filter(m -> m.getName().equals("isBlank")).count();
+       assertEquals(1,c);
+    }
+
+    public void xtestJava18accessing19JRT() throws ClassFormatException, IOException {
+       if (LangUtil.getVmVersion()>8) fail("Must be Java 8");
+       List<String> classpath = new ArrayList<>();
+       classpath.add(java9_jrtfsjar);
+       ClassPathManager cpm = new ClassPathManager(classpath, new MH());
+       ClassFile t = cpm.find(UnresolvedType.forSignature("Ljava/lang/String;"));
+       assertNotNull(t);
+       ClassParser classParser = new ClassParser(t.getInputStream(),t.getPath());
+       JavaClass clazz = classParser.parse();
+       // isBlank() exists on Java 11, but not on Java9
+       long c = Arrays.asList(clazz.getMethods()).stream().filter(m -> m.getName().equals("isBlank")).count();
+       assertEquals(0,c);
+    }
+
+    
+    public void xtestSanity19accessing18RTJAR() throws IOException {
+       assertEquals(9.0,LangUtil.getVmVersion());
+       List<String> classpath = new ArrayList<>();
+       classpath.add(java18_rtjar);
+       ClassPathManager cpm = new ClassPathManager(classpath, new MH());
+       ClassFile t = cpm.find(UnresolvedType.forSignature("Ljava/lang/Object;"));
+       assertNotNull(t);       
+    }
+    
+    public void xtestJava19accessing11JRT() throws ClassFormatException, IOException {
+       assertEquals(9.0,LangUtil.getVmVersion());
+       List<String> classpath = new ArrayList<>();
+       classpath.add(java11_jrtfsjar);
+       ClassPathManager cpm = new ClassPathManager(classpath, new MH());
+       ClassFile t = cpm.find(UnresolvedType.forSignature("Ljava/lang/String;"));
+       assertNotNull(t);
+       ClassParser classParser = new ClassParser(t.getInputStream(),t.getPath());
+       JavaClass clazz = classParser.parse();
+       // isBlank() exists on Java 11
+       long c = Arrays.asList(clazz.getMethods()).stream().filter(m -> m.getName().equals("isBlank")).count();
+       assertEquals(1,c);
+    }
+
+    public void xtestJava19accessing19JRT() throws ClassFormatException, IOException {
+       assertEquals(9.0,LangUtil.getVmVersion());
+       List<String> classpath = new ArrayList<>();
+       classpath.add(java9_jrtfsjar);
+       ClassPathManager cpm = new ClassPathManager(classpath, new MH());
+       ClassFile t = cpm.find(UnresolvedType.forSignature("Ljava/lang/String;"));
+       assertNotNull(t);
+       ClassParser classParser = new ClassParser(t.getInputStream(),t.getPath());
+       JavaClass clazz = classParser.parse();
+       // isBlank() exists on Java 11, but not on Java9
+       long c = Arrays.asList(clazz.getMethods()).stream().filter(m -> m.getName().equals("isBlank")).count();
+       assertEquals(0,c);
+    }
+    
+    public void xtestSanity11accessing18RTJAR() throws IOException {
+       assertEquals(11.0,LangUtil.getVmVersion());
+       List<String> classpath = new ArrayList<>();
+       classpath.add(java18_rtjar);
+       ClassPathManager cpm = new ClassPathManager(classpath, new MH());
+       ClassFile t = cpm.find(UnresolvedType.forSignature("Ljava/lang/Object;"));
+       assertNotNull(t);       
+    }
+    
+    public void xtestJava11accessing11JRT() throws ClassFormatException, IOException {
+       assertEquals(11.0,LangUtil.getVmVersion());
+       List<String> classpath = new ArrayList<>();
+       classpath.add(java11_jrtfsjar);
+       ClassPathManager cpm = new ClassPathManager(classpath, new MH());
+       ClassFile t = cpm.find(UnresolvedType.forSignature("Ljava/lang/String;"));
+       assertNotNull(t);
+       ClassParser classParser = new ClassParser(t.getInputStream(),t.getPath());
+       JavaClass clazz = classParser.parse();
+       // isBlank() exists on Java 11
+       long c = Arrays.asList(clazz.getMethods()).stream().filter(m -> m.getName().equals("isBlank")).count();
+       assertEquals(1,c);
+    }
+
+    public void xtestJava11accessing19JRT() throws ClassFormatException, IOException {
+       assertEquals(11.0,LangUtil.getVmVersion());
+       List<String> classpath = new ArrayList<>();
+       classpath.add(java9_jrtfsjar);
+       ClassPathManager cpm = new ClassPathManager(classpath, new MH());
+       ClassFile t = cpm.find(UnresolvedType.forSignature("Ljava/lang/String;"));
+       assertNotNull(t);
+       ClassParser classParser = new ClassParser(t.getInputStream(),t.getPath());
+       JavaClass clazz = classParser.parse();
+       // isBlank() exists on Java 11, but not on Java9
+       long c = Arrays.asList(clazz.getMethods()).stream().filter(m -> m.getName().equals("isBlank")).count();
+       assertEquals(0,c);
+    }
+    
+    static class MH implements IMessageHandler {
+
+               @Override
+               public boolean handleMessage(IMessage message) throws AbortException {
+                       System.out.println(message);
+                       return false;
+               }
+
+               @Override
+               public boolean isIgnoring(Kind kind) {
+                       return false;
+               }
+
+               @Override
+               public void dontIgnore(Kind kind) {
+               }
+
+               @Override
+               public void ignore(Kind kind) {
+               }
+       
+    }
+}
index 6e89c675c470445a75ee44bcdc363ba511110f99..abb8c08b2973160924da1dcb35f1f8c9cf135a11 100644 (file)
@@ -70,7 +70,7 @@ public class JImageTestCase extends TestCase {
                if (!LangUtil.is19VMOrGreater()) return;
                JImageEntry jie = getJImageEntry();
                
-               Map<String, Path> packageCache = JImageEntry.getPackageCache();
+               Map<String, Path> packageCache = jie.getPackageCache();
                assertTrue(packageCache.size()>0);
                // Note: seems to be about 1625 entries in it for Java9
                Path path = packageCache.get("java/lang");