Browse Source

Final bits of AspectJ 1.9.4

tags/V1_9_4
Andy Clement 5 years ago
parent
commit
2db13f12ae

+ 46
- 0
docs/dist/doc/README-194.html View File

@@ -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>

+ 1
- 0
docs/dist/doc/index.html View File

@@ -138,6 +138,7 @@
<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>,

+ 1
- 1
org.aspectj.lib/pom.xml View 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>


+ 2
- 2
org.eclipse.jdt.core/pom.xml View 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>

+ 1
- 1
pom.xml View File

@@ -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>


+ 65
- 27
weaver/src/main/java/org/aspectj/weaver/bcel/ClassPathManager.java View 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;
}

}

+ 214
- 0
weaver/src/test/java/org/aspectj/weaver/bcel/ClasspathManagerTestCase.java View File

@@ -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) {
}
}
}

+ 1
- 1
weaver/src/test/java/org/aspectj/weaver/bcel/JImageTestCase.java View 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");

Loading…
Cancel
Save