commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ggreg...@apache.org
Subject svn commit: r1836939 - in /commons/proper/bcel/trunk/src: main/java/org/apache/bcel/util/ test/java/org/apache/bcel/generic/ test/java/org/apache/bcel/util/
Date Sat, 28 Jul 2018 17:54:09 GMT
Author: ggregory
Date: Sat Jul 28 17:54:09 2018
New Revision: 1836939

URL: http://svn.apache.org/viewvc?rev=1836939&view=rev
Log:
[BCEL-305] ClassPath.getClassFile() and friends do not work with JRE 9 and higher. Test classes
in the Java 9 and above modular runtime image file, AKA the monolithic "/modules" files. This
uses the JRT file system on Java 9 only. Tests are skipped on Java 8 and below.

Added:
    commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/ModularRuntimeImage.java
    commons/proper/bcel/trunk/src/test/java/org/apache/bcel/util/ModularRuntimeImageTestCase.java
Modified:
    commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/ClassPath.java
    commons/proper/bcel/trunk/src/test/java/org/apache/bcel/generic/JdkGenericDumpTestCase.java

Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/ClassPath.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/ClassPath.java?rev=1836939&r1=1836938&r2=1836939&view=diff
==============================================================================
--- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/ClassPath.java (original)
+++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/ClassPath.java Sat Jul 28
17:54:09 2018
@@ -25,23 +25,15 @@ import java.io.FilenameFilter;
 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.DirectoryStream;
-import java.nio.file.FileSystem;
-import java.nio.file.FileSystems;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.Enumeration;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
-import java.util.Map;
 import java.util.Objects;
 import java.util.StringTokenizer;
 import java.util.Vector;
@@ -358,34 +350,16 @@ public class ClassPath implements Closea
 
     private static class JrtModules extends AbstractPathEntry {
 
-        private final URLClassLoader classLoader;
-        private final FileSystem jrtFileSystem;
+        private final ModularRuntimeImage modularRuntimeImage;
         private final JrtModule[] modules;
 
-        @SuppressWarnings("resource")
-        public JrtModules() {
-            final List<JrtModule> list = new ArrayList<>();
-            final Map<String, ?> emptyMap = Collections.emptyMap();
-            final Path jrePath = Paths.get(System.getProperty("java.home"));
-            final Path jrtFsPath = jrePath.resolve("lib").resolve("jrt-fs.jar");
-            URLClassLoader tempClassLoader = null;
-            FileSystem tempFs = null;
-            try {
-                tempClassLoader = new URLClassLoader(new URL[] {jrtFsPath.toUri().toURL()
});
-                tempFs = FileSystems.newFileSystem(URI.create("jrt:/"), emptyMap, tempClassLoader);
-                try (DirectoryStream<Path> ds = Files.newDirectoryStream(tempFs.getPath("/modules")))
{
-                    final Iterator<Path> iterator = ds.iterator();
-                    while (iterator.hasNext()) {
-                        list.add(new JrtModule(iterator.next()));
-                    }
-                }
-            } catch (final IOException e) {
-                // TODO ?
-                e.printStackTrace();
+        public JrtModules(String path) throws IOException {
+            this.modularRuntimeImage = new ModularRuntimeImage();
+            final List<Path> list = modularRuntimeImage.list(path);
+            this.modules = new JrtModule[list.size()];
+            for (int i = 0; i < modules.length; i++) {
+                modules[i] = new JrtModule(list.get(i));
             }
-            this.classLoader = tempClassLoader;
-            this.jrtFileSystem = tempFs;
-            this.modules = list.toArray(new JrtModule[list.size()]);
         }
 
         @Override
@@ -396,11 +370,8 @@ public class ClassPath implements Closea
                     modules[i].close();
                 }
             }
-            if (classLoader != null) {
-                classLoader.close();
-            }
-            if (jrtFileSystem != null) {
-                jrtFileSystem.close();
+            if (modularRuntimeImage != null) {
+                modularRuntimeImage.close();
             }
         }
 
@@ -603,8 +574,8 @@ public class ClassPath implements Closea
                             list.add(new Dir(path));
                         } else if (path.endsWith(".jmod")) {
                             list.add(new Module(new ZipFile(file)));
-                        } else if (path.endsWith(File.separator + "modules")) {
-                            list.add(new JrtModules());
+                        } else if (path.endsWith(ModularRuntimeImage.MODULES_PATH)) {
+                            list.add(new JrtModules(ModularRuntimeImage.MODULES_PATH));
                         } else {
                             list.add(new Jar(new ZipFile(file)));
                         }

Added: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/ModularRuntimeImage.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/ModularRuntimeImage.java?rev=1836939&view=auto
==============================================================================
--- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/ModularRuntimeImage.java
(added)
+++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/ModularRuntimeImage.java
Sat Jul 28 17:54:09 2018
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.bcel.util;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Wraps a Java 9 JEP 220 modular runtime image. Requires the JRT NIO file system.
+ *
+ * @since 6.3
+ */
+public class ModularRuntimeImage implements Closeable {
+
+    static final String MODULES_PATH = File.separator + "modules";
+    static final String PACKAGES_PATH = File.separator + "packages";
+
+    private final URLClassLoader classLoader;
+    private final FileSystem fileSystem;
+
+    /**
+     * Constructs a default instance.
+     *
+     * @throws IOException
+     *             an I/O error occurs accessing the file system
+     */
+    public ModularRuntimeImage() throws IOException {
+        this(null, FileSystems.getFileSystem(URI.create("jrt:/")));
+    }
+
+    /**
+     * Constructs an instance using the JRT file system implementation from a specific Java
Home.
+     *
+     * @param javaHome
+     *            Path to a Java 9 or greater home.
+     *
+     * @throws IOException
+     *             an I/O error occurs accessing the file system
+     */
+    public ModularRuntimeImage(final String javaHome) throws IOException {
+        final Map<String, ?> emptyMap = Collections.emptyMap();
+        final Path jrePath = Paths.get(javaHome);
+        final Path jrtFsPath = jrePath.resolve("lib").resolve("jrt-fs.jar");
+        this.classLoader = new URLClassLoader(new URL[] {jrtFsPath.toUri().toURL() });
+        this.fileSystem = FileSystems.newFileSystem(URI.create("jrt:/"), emptyMap, classLoader);
+    }
+
+    private ModularRuntimeImage(final URLClassLoader cl, final FileSystem fs) {
+        this.classLoader = cl;
+        this.fileSystem = fs;
+    }
+
+    @Override
+    public void close() throws IOException {
+        if (classLoader != null) {
+            if (classLoader != null) {
+                classLoader.close();
+            }
+            if (fileSystem != null) {
+                fileSystem.close();
+            }
+        }
+    }
+
+    /**
+     * Lists all entries in the given directory.
+     *
+     * @param dirPath
+     *            directory path.
+     * @return a list of dir entries if an I/O error occurs
+     * @throws IOException
+     *             an I/O error occurs accessing the file system
+     */
+    public List<Path> list(final Path dirPath) throws IOException {
+        final List<Path> list = new ArrayList<>();
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(dirPath)) {
+            final Iterator<Path> iterator = ds.iterator();
+            while (iterator.hasNext()) {
+                list.add(iterator.next());
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Lists all entries in the given directory.
+     *
+     * @param dirName
+     *            directory path.
+     * @return a list of dir entries if an I/O error occurs
+     * @throws IOException
+     *             an I/O error occurs accessing the file system
+     */
+    public List<Path> list(final String dirName) throws IOException {
+        return list(fileSystem.getPath(dirName));
+    }
+
+    /**
+     * Lists all modules.
+     *
+     * @return a list of modules
+     * @throws IOException
+     *             an I/O error occurs accessing the file system
+     */
+    public List<Path> modules() throws IOException {
+        return list(MODULES_PATH);
+    }
+
+    /**
+     * Lists all packages.
+     *
+     * @return a list of modules
+     * @throws IOException
+     *             an I/O error occurs accessing the file system
+     */
+    public List<Path> packages() throws IOException {
+        return list(PACKAGES_PATH);
+    }
+
+    public FileSystem getFileSystem() {
+        return fileSystem;
+    }
+
+}

Modified: commons/proper/bcel/trunk/src/test/java/org/apache/bcel/generic/JdkGenericDumpTestCase.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/test/java/org/apache/bcel/generic/JdkGenericDumpTestCase.java?rev=1836939&r1=1836938&r2=1836939&view=diff
==============================================================================
--- commons/proper/bcel/trunk/src/test/java/org/apache/bcel/generic/JdkGenericDumpTestCase.java
(original)
+++ commons/proper/bcel/trunk/src/test/java/org/apache/bcel/generic/JdkGenericDumpTestCase.java
Sat Jul 28 17:54:09 2018
@@ -23,10 +23,19 @@ import static org.junit.Assert.fail;
 
 import java.io.File;
 import java.io.FileFilter;
+import java.io.IOException;
 import java.io.InputStream;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.PathMatcher;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
 import java.util.Collection;
 import java.util.Enumeration;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
@@ -35,8 +44,12 @@ import org.apache.bcel.classfile.ClassPa
 import org.apache.bcel.classfile.Code;
 import org.apache.bcel.classfile.JavaClass;
 import org.apache.bcel.classfile.Method;
+import org.apache.bcel.util.ModularRuntimeImage;
+import org.apache.commons.lang3.JavaVersion;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.SystemUtils;
+import org.junit.Assert;
+import org.junit.Assume;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -51,6 +64,45 @@ import com.sun.jna.platform.win32.Advapi
 @RunWith(Parameterized.class)
 public class JdkGenericDumpTestCase {
 
+    private static class ClassParserFilesVisitor extends SimpleFileVisitor<Path> {
+
+        private final PathMatcher matcher;
+
+        ClassParserFilesVisitor(final String pattern) {
+            matcher = FileSystems.getDefault().getPathMatcher("glob:" + pattern);
+        }
+
+        private void find(final Path path) throws IOException {
+            final Path name = path.getFileName();
+            if (name != null && matcher.matches(name)) {
+                try (final InputStream inputStream = Files.newInputStream(path)) {
+                    final ClassParser parser = new ClassParser(inputStream, name.toAbsolutePath().toString());
+                    final JavaClass jc = parser.parse();
+                    Assert.assertNotNull(jc);
+                }
+
+            }
+        }
+
+        @Override
+        public FileVisitResult preVisitDirectory(final Path dir, final BasicFileAttributes
attrs) throws IOException {
+            find(dir);
+            return FileVisitResult.CONTINUE;
+        }
+
+        @Override
+        public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs)
throws IOException {
+            find(file);
+            return FileVisitResult.CONTINUE;
+        }
+
+        @Override
+        public FileVisitResult visitFileFailed(final Path file, final IOException e) {
+            System.err.println(e);
+            return FileVisitResult.CONTINUE;
+        }
+    }
+
     private static final char[] hexArray = "0123456789ABCDEF".toCharArray();
 
     private static final String KEY_JDK = "SOFTWARE\\JavaSoft\\Java Development Kit";
@@ -206,4 +258,17 @@ public class JdkGenericDumpTestCase {
             }
         }
     }
+
+    @Test
+    public void testJreModules() throws Exception {
+        Assume.assumeTrue(SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_9));
+        try (final ModularRuntimeImage mri = new ModularRuntimeImage(javaHome)) {
+            final List<Path> modules = mri.modules();
+            Assert.assertFalse(modules.isEmpty());
+            for (final Path path : modules) {
+                Files.walkFileTree(path, new ClassParserFilesVisitor("*.class"));
+            }
+        }
+    }
+
 }

Added: commons/proper/bcel/trunk/src/test/java/org/apache/bcel/util/ModularRuntimeImageTestCase.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/test/java/org/apache/bcel/util/ModularRuntimeImageTestCase.java?rev=1836939&view=auto
==============================================================================
--- commons/proper/bcel/trunk/src/test/java/org/apache/bcel/util/ModularRuntimeImageTestCase.java
(added)
+++ commons/proper/bcel/trunk/src/test/java/org/apache/bcel/util/ModularRuntimeImageTestCase.java
Sat Jul 28 17:54:09 2018
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.bcel.util;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.bcel.generic.JdkGenericDumpTestCase;
+import org.apache.commons.lang3.JavaVersion;
+import org.apache.commons.lang3.SystemUtils;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * Tests {@link ModularRuntimeImage}.
+ */
+@RunWith(Parameterized.class)
+public class ModularRuntimeImageTestCase {
+
+    @Parameters(name = "{0}")
+    public static Collection<String> data() {
+        return JdkGenericDumpTestCase.data();
+    }
+
+    private final String javaHome;
+    private final ModularRuntimeImage modularRuntimeImage;
+
+    public ModularRuntimeImageTestCase(final String javaHome) throws IOException {
+        this.javaHome = javaHome;
+        Assume.assumeTrue(SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_9));
+        this.modularRuntimeImage = new ModularRuntimeImage(javaHome);
+    }
+
+    @Test
+    public void testListJreModules() throws IOException {
+        final List<Path> listEntries = modularRuntimeImage.list(ModularRuntimeImage.MODULES_PATH);
+        Assert.assertFalse(listEntries.isEmpty());
+        Assert.assertTrue(listEntries.toString().indexOf("/java.base") > -1);
+    }
+
+    @Test
+    public void testListJreModule() throws IOException {
+        final List<Path> listEntries = modularRuntimeImage.list(ModularRuntimeImage.MODULES_PATH
+ "/java.base");
+        Assert.assertFalse(listEntries.isEmpty());
+        Assert.assertTrue(listEntries.toString().indexOf("/java.base") > -1);
+    }
+
+    @Test
+    public void testListJreModulePackageDir() throws IOException {
+        final List<Path> listEntries = modularRuntimeImage
+                .list(ModularRuntimeImage.MODULES_PATH + "/java.base/java/lang");
+        Assert.assertFalse(listEntries.isEmpty());
+        Assert.assertTrue(listEntries.toString().indexOf("/java.base/java/lang/String.class")
> -1);
+    }
+
+    @Test
+    public void testListJrePackages() throws IOException {
+        final List<Path> listEntries = modularRuntimeImage.list(ModularRuntimeImage.PACKAGES_PATH);
+        Assert.assertFalse(listEntries.isEmpty());
+        Assert.assertTrue(listEntries.toString().indexOf("java.lang") > -1);
+    }
+}



Mime
View raw message