From a3a3bdf9aedf775fccfd5644c7223c6d493ed8b1 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov Date: Mon, 17 Oct 2011 16:35:29 +0400 Subject: SONAR-2892 Remove dependency on plexus-classworlds from sonar-squid-java-plugin --- plugins/sonar-squid-java-plugin/pom.xml | 5 -- .../org/sonar/java/bytecode/BytecodeScanner.java | 2 +- .../sonar/java/bytecode/ClassLoaderBuilder.java | 73 ++++++++++++++++ .../java/bytecode/ClassworldsClassLoader.java | 95 --------------------- .../java/bytecode/ClassworldsClassLoaderTest.java | 98 ---------------------- .../bytecode/asm/AsmClassProviderImplTest.java | 4 +- .../java/bytecode/asm/AsmClassVisitorTest.java | 4 +- .../java/bytecode/asm/AsmFieldVisitorTest.java | 4 +- .../java/bytecode/asm/AsmMethodVisitorTest.java | 4 +- .../sonar/java/bytecode/loader/JarLoaderTest.java | 56 +++++++++++++ .../java/bytecode/visitor/AccessorVisitorTest.java | 4 +- 11 files changed, 140 insertions(+), 209 deletions(-) create mode 100644 plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/ClassLoaderBuilder.java delete mode 100644 plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/ClassworldsClassLoader.java delete mode 100644 plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/ClassworldsClassLoaderTest.java create mode 100644 plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/loader/JarLoaderTest.java (limited to 'plugins') diff --git a/plugins/sonar-squid-java-plugin/pom.xml b/plugins/sonar-squid-java-plugin/pom.xml index 3cd7b8b5602..11b76dbdf15 100644 --- a/plugins/sonar-squid-java-plugin/pom.xml +++ b/plugins/sonar-squid-java-plugin/pom.xml @@ -75,11 +75,6 @@ commons-io provided - - org.codehaus.plexus - plexus-classworlds - provided - org.codehaus.sonar diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/BytecodeScanner.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/BytecodeScanner.java index 1b4fd37b50b..ac2a8c8a75c 100644 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/BytecodeScanner.java +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/BytecodeScanner.java @@ -46,7 +46,7 @@ public class BytecodeScanner extends CodeScanner { public BytecodeScanner scan(Collection bytecodeFilesOrDirectories) { Collection classes = indexer.search(new QueryByType(SourceClass.class)); - ClassLoader classLoader = ClassworldsClassLoader.create(bytecodeFilesOrDirectories); + ClassLoader classLoader = ClassLoaderBuilder.create(bytecodeFilesOrDirectories); scan(classes, new AsmClassProviderImpl(classLoader)); ((SquidClassLoader) classLoader).close(); // TODO unchecked cast return this; diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/ClassLoaderBuilder.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/ClassLoaderBuilder.java new file mode 100644 index 00000000000..a271689774d --- /dev/null +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/ClassLoaderBuilder.java @@ -0,0 +1,73 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.java.bytecode; + +import java.io.File; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.java.bytecode.loader.SquidClassLoader; + +import com.google.common.collect.Lists; + +public final class ClassLoaderBuilder { + + private static final Logger LOG = LoggerFactory.getLogger(ClassLoaderBuilder.class); + + private ClassLoaderBuilder() { + // only static methods + } + + public static ClassLoader create(Collection bytecodeFilesOrDirectories) { + List files = Lists.newArrayList(); + for (File file : bytecodeFilesOrDirectories) { + if (file.isFile() && file.getPath().endsWith(".class")) { + LOG.info("Sonar Squid ClassLoader was expecting a JAR file instead of CLASS file : '" + file.getAbsolutePath() + "'"); + } else { + files.add(file); + } + } + + if (LOG.isDebugEnabled()) { + LOG.debug("----- Classpath analyzed by Squid:"); + for (File file : files) { + LOG.debug(file.getAbsolutePath()); + } + LOG.debug("-----"); + } + + try { + return new SquidClassLoader(files); + } catch (Exception e) { + throw new IllegalStateException("Can not create ClassLoader", e); + } + } + + /** + * For tests. + */ + public static ClassLoader create(File bytecodeFileOrDirectory) { + return create(Arrays.asList(bytecodeFileOrDirectory)); + } + +} diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/ClassworldsClassLoader.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/ClassworldsClassLoader.java deleted file mode 100644 index c4eabb0edc3..00000000000 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/ClassworldsClassLoader.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2011 SonarSource - * mailto:contact AT sonarsource DOT com - * - * Sonar is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * Sonar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.java.bytecode; - -import java.io.File; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Arrays; -import java.util.Collection; - -import org.codehaus.classworlds.ClassRealm; -import org.codehaus.classworlds.ClassWorld; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.java.bytecode.loader.SquidClassLoader; - -public final class ClassworldsClassLoader { - - private static final Logger LOG = LoggerFactory.getLogger(ClassworldsClassLoader.class); - - private ClassworldsClassLoader() { - // only static methods - } - - public static ClassLoader create(File bytecodeFileOrDirectory) { - return create(Arrays.asList(bytecodeFileOrDirectory)); - } - - public static ClassLoader create(Collection bytecodeFilesOrDirectories) { - try { - return new SquidClassLoader(bytecodeFilesOrDirectories); - } catch (Exception e) { - throw new IllegalStateException("Can not create classloader", e); - } - } - - public static ClassLoader createUsingClassWorld(Collection bytecodeFilesOrDirectories) { - try { - ClassWorld world = new ClassWorld(); - ClassRealm realm = world.newRealm("squid.project", null /* explicit declaration that parent should be bootstrap class loader */); - - for (File bytecode : bytecodeFilesOrDirectories) { - URL url = getURL(bytecode); - if (bytecode.isFile() && url.toString().endsWith(".class")) { - LOG.info("Sonar Squid ClassLoader was expecting a JAR file instead of CLASS file : '" + bytecode.getAbsolutePath() + "'"); - } else { - // JAR file or directory - realm.addConstituent(url); - } - } - - if (LOG.isDebugEnabled()) { - LOG.debug("----- Classpath analyzed by Squid:"); - for (URL url : realm.getConstituents()) { - LOG.debug(url.toString()); - } - LOG.debug("-----"); - } - - return realm.getClassLoader(); - - } catch (Exception e) { - throw new IllegalStateException("Can not create classloader", e); - } - } - - private static URL getURL(File file) throws MalformedURLException { - URL url = file.toURI().toURL(); - if (file.isDirectory() && !url.toString().endsWith("/")) { - /* - * See ClassRealm javadoc : If the constituent is a directory, then the URL must end with a slash (/). Otherwise the constituent will - * be treated as a JAR file. - */ - url = new URL(url.toString() + "/"); - } - return url; - } -} \ No newline at end of file diff --git a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/ClassworldsClassLoaderTest.java b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/ClassworldsClassLoaderTest.java deleted file mode 100644 index fbb6b836094..00000000000 --- a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/ClassworldsClassLoaderTest.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2011 SonarSource - * mailto:contact AT sonarsource DOT com - * - * Sonar is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * Sonar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.java.bytecode; - -import org.codehaus.classworlds.ClassWorld; -import org.junit.Test; -import org.sonar.java.ast.SquidTestUtils; - -import java.io.File; -import java.util.Collections; - -import static org.hamcrest.CoreMatchers.nullValue; -import static org.hamcrest.core.IsNot.not; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.fail; - -public class ClassworldsClassLoaderTest { - - @Test - public void createManyTimes() { - // check that the method create() can be executed more than once - assertThat(ClassworldsClassLoader.create(Collections.emptyList()), not(nullValue())); - assertThat(ClassworldsClassLoader.create(Collections.emptyList()), not(nullValue())); - } - - /** - * See SONAR-2824: - * ClassLoader created by {@link ClassworldsClassLoader}, - * should be able to load classes only from JDK and from provided list of JAR-files, - * thus it shouldn't be able to load class {@link ClassWorld}. - */ - @Test - public void shouldBeIsolated() throws ClassNotFoundException { - ClassLoader classloader = ClassworldsClassLoader.create(Collections.EMPTY_LIST); - try { - classloader.loadClass(ClassWorld.class.getName()); - fail(); - } catch (ClassNotFoundException e) { - // ok - } - assertThat(classloader.loadClass("java.lang.Integer"), not(nullValue())); - assertThat(classloader.getResource("java/lang/Integer.class"), not(nullValue())); - } - - @Test - public void createFromDirectory() throws ClassNotFoundException { - File dir = SquidTestUtils.getFile("/bytecode/bin/"); - ClassLoader classloader = ClassworldsClassLoader.create(dir); - assertThat(classloader.loadClass("tags.TagName"), not(nullValue())); - assertThat(classloader.getResource("tags/TagName.class"), not(nullValue())); - - try { - classloader.loadClass("tags.Unknown"); - fail(); - } catch (ClassNotFoundException e) { - // ok - } - } - - @Test - public void createFromJar() throws ClassNotFoundException { - File jar = SquidTestUtils.getFile("/bytecode/lib/hello.jar"); - ClassLoader classloader = ClassworldsClassLoader.create(jar); - assertThat(classloader.loadClass("org.sonar.tests.Hello"), not(nullValue())); - assertThat(classloader.getResource("org/sonar/tests/Hello.class"), not(nullValue())); - - try { - classloader.loadClass("foo.Unknown"); - fail(); - } catch (ClassNotFoundException e) { - // ok - } - } - - @Test - public void unknownJarIsIgnored() throws ClassNotFoundException { - File jar = SquidTestUtils.getFile("/bytecode/lib/unknown.jar"); - ClassLoader classloader = ClassworldsClassLoader.create(jar); - assertThat(classloader.getResource("org/sonar/tests/Hello.class"), nullValue()); - } -} diff --git a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/asm/AsmClassProviderImplTest.java b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/asm/AsmClassProviderImplTest.java index 11cc7981700..e1e824dbe83 100644 --- a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/asm/AsmClassProviderImplTest.java +++ b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/asm/AsmClassProviderImplTest.java @@ -21,7 +21,7 @@ package org.sonar.java.bytecode.asm; import org.junit.Test; import org.sonar.java.ast.SquidTestUtils; -import org.sonar.java.bytecode.ClassworldsClassLoader; +import org.sonar.java.bytecode.ClassLoaderBuilder; import org.sonar.java.bytecode.asm.AsmClassProvider.DETAIL_LEVEL; import static org.junit.Assert.assertEquals; @@ -85,7 +85,7 @@ public class AsmClassProviderImplTest { @Test public void testPersonalClassLoader() { - asmClassProviderImpl = new AsmClassProviderImpl(ClassworldsClassLoader.create(SquidTestUtils.getFile("/bytecode/bin/"))); + asmClassProviderImpl = new AsmClassProviderImpl(ClassLoaderBuilder.create(SquidTestUtils.getFile("/bytecode/bin/"))); assertEquals(DETAIL_LEVEL.STRUCTURE_AND_CALLS, asmClassProviderImpl.getClass("tags/Line", DETAIL_LEVEL.STRUCTURE_AND_CALLS).getDetailLevel()); } } diff --git a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/asm/AsmClassVisitorTest.java b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/asm/AsmClassVisitorTest.java index 7e1b7a3f188..4933b8c525b 100644 --- a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/asm/AsmClassVisitorTest.java +++ b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/asm/AsmClassVisitorTest.java @@ -21,7 +21,7 @@ package org.sonar.java.bytecode.asm; import org.junit.Test; import org.sonar.java.ast.SquidTestUtils; -import org.sonar.java.bytecode.ClassworldsClassLoader; +import org.sonar.java.bytecode.ClassLoaderBuilder; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -30,7 +30,7 @@ import static org.junit.Assert.assertTrue; public class AsmClassVisitorTest { - private static AsmClassProvider asmClassProvider = new AsmClassProviderImpl(ClassworldsClassLoader.create(SquidTestUtils.getFile("/bytecode/bin/"))); + private static AsmClassProvider asmClassProvider = new AsmClassProviderImpl(ClassLoaderBuilder.create(SquidTestUtils.getFile("/bytecode/bin/"))); @Test public void testVisit() { diff --git a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/asm/AsmFieldVisitorTest.java b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/asm/AsmFieldVisitorTest.java index 40a73f6e0b7..1c1eb324eea 100644 --- a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/asm/AsmFieldVisitorTest.java +++ b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/asm/AsmFieldVisitorTest.java @@ -21,7 +21,7 @@ package org.sonar.java.bytecode.asm; import org.junit.Test; import org.sonar.java.ast.SquidTestUtils; -import org.sonar.java.bytecode.ClassworldsClassLoader; +import org.sonar.java.bytecode.ClassLoaderBuilder; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -30,7 +30,7 @@ public class AsmFieldVisitorTest { @Test public void testVisitStringField() { - AsmClassProviderImpl classProvider = new AsmClassProviderImpl(ClassworldsClassLoader.create(SquidTestUtils.getFile("/bytecode/bin/"))); + AsmClassProviderImpl classProvider = new AsmClassProviderImpl(ClassLoaderBuilder.create(SquidTestUtils.getFile("/bytecode/bin/"))); AsmClass fileClass = classProvider.getClass("tags/SourceFile"); assertEquals(5, fileClass.getFields().size()); AsmField field = fileClass.getField("path"); diff --git a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/asm/AsmMethodVisitorTest.java b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/asm/AsmMethodVisitorTest.java index a1d8324c440..00f7849dc92 100644 --- a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/asm/AsmMethodVisitorTest.java +++ b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/asm/AsmMethodVisitorTest.java @@ -21,13 +21,13 @@ package org.sonar.java.bytecode.asm; import org.junit.Test; import org.sonar.java.ast.SquidTestUtils; -import org.sonar.java.bytecode.ClassworldsClassLoader; +import org.sonar.java.bytecode.ClassLoaderBuilder; import static org.junit.Assert.*; public class AsmMethodVisitorTest { - private AsmClassProvider asmClassProvider = new AsmClassProviderImpl(ClassworldsClassLoader.create(SquidTestUtils.getFile("/bytecode/bin/"))); + private AsmClassProvider asmClassProvider = new AsmClassProviderImpl(ClassLoaderBuilder.create(SquidTestUtils.getFile("/bytecode/bin/"))); @Test public void testVisitFieldInsn() { diff --git a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/loader/JarLoaderTest.java b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/loader/JarLoaderTest.java new file mode 100644 index 00000000000..4fd70f11f99 --- /dev/null +++ b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/loader/JarLoaderTest.java @@ -0,0 +1,56 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.java.bytecode.loader; + +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.endsWith; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.startsWith; +import static org.junit.Assert.assertThat; + +import java.io.File; +import java.io.InputStream; +import java.net.URL; + +import org.apache.commons.io.IOUtils; +import org.junit.Test; +import org.sonar.java.ast.SquidTestUtils; + +public class JarLoaderTest { + + @Test + public void testFindResource() throws Exception { + File jar = SquidTestUtils.getFile("/bytecode/lib/hello.jar"); + JarLoader jarLoader = new JarLoader(jar); + + URL url = jarLoader.findResource("META-INF/MANIFEST.MF"); + assertThat(url.toString(), allOf(startsWith("jar:"), endsWith("/bytecode/lib/hello.jar!/META-INF/MANIFEST.MF"))); + + InputStream is = url.openStream(); + try { + assertThat(IOUtils.readLines(is), hasItem("Manifest-Version: 1.0")); + } finally { + IOUtils.closeQuietly(is); + } + + jarLoader.close(); + } + +} diff --git a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/visitor/AccessorVisitorTest.java b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/visitor/AccessorVisitorTest.java index 3b81a45c2c0..152589f1ee3 100644 --- a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/visitor/AccessorVisitorTest.java +++ b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/bytecode/visitor/AccessorVisitorTest.java @@ -22,7 +22,7 @@ package org.sonar.java.bytecode.visitor; import org.junit.BeforeClass; import org.junit.Test; import org.sonar.java.ast.SquidTestUtils; -import org.sonar.java.bytecode.ClassworldsClassLoader; +import org.sonar.java.bytecode.ClassLoaderBuilder; import org.sonar.java.bytecode.asm.AsmClass; import org.sonar.java.bytecode.asm.AsmClassProvider; import org.sonar.java.bytecode.asm.AsmClassProviderImpl; @@ -38,7 +38,7 @@ public class AccessorVisitorTest { @BeforeClass public static void init() { - asmClassProvider = new AsmClassProviderImpl(ClassworldsClassLoader.create(SquidTestUtils.getFile("/bytecode/bin/"))); + asmClassProvider = new AsmClassProviderImpl(ClassLoaderBuilder.create(SquidTestUtils.getFile("/bytecode/bin/"))); javaBean = asmClassProvider.getClass("properties/JavaBean"); accessorVisitor.visitClass(javaBean); for (AsmMethod method : javaBean.getMethods()) { -- cgit v1.2.3