diff --git a/src/main/java/org/apache/maven/plugins/pmd/exec/Executor.java b/src/main/java/org/apache/maven/plugins/pmd/exec/Executor.java index ca17511e..b4636d15 100644 --- a/src/main/java/org/apache/maven/plugins/pmd/exec/Executor.java +++ b/src/main/java/org/apache/maven/plugins/pmd/exec/Executor.java @@ -25,8 +25,11 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.UnsupportedEncodingException; import java.net.URL; import java.net.URLClassLoader; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.SimpleFormatter; @@ -125,17 +128,23 @@ protected static String buildClasspath() return classpath.toString(); } - private static void buildClasspath( StringBuilder classpath, ClassLoader cl ) + static void buildClasspath( StringBuilder classpath, ClassLoader cl ) { if ( cl instanceof URLClassLoader ) { for ( URL url : ( (URLClassLoader) cl ).getURLs() ) { - String urlString = url.toString(); - if ( urlString.startsWith( "file:" ) ) + if ( "file".equalsIgnoreCase( url.getProtocol() ) ) { - String f = urlString.substring( 5 ); // strip "file:" - classpath.append( f ).append( File.pathSeparatorChar ); + try + { + String filename = URLDecoder.decode( url.getPath(), StandardCharsets.UTF_8.name() ); + classpath.append( new File( filename ).getPath() ).append( File.pathSeparatorChar ); + } + catch ( UnsupportedEncodingException e ) + { + LOG.warn( "Ignoring " + url + " in classpath due to UnsupportedEncodingException", e ); + } } } } diff --git a/src/test/java/org/apache/maven/plugins/pmd/exec/ExecutorTest.java b/src/test/java/org/apache/maven/plugins/pmd/exec/ExecutorTest.java new file mode 100644 index 00000000..67dad92c --- /dev/null +++ b/src/test/java/org/apache/maven/plugins/pmd/exec/ExecutorTest.java @@ -0,0 +1,48 @@ +package org.apache.maven.plugins.pmd.exec; + +/* + * 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. + */ + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; + +import org.apache.commons.lang3.SystemUtils; +import org.junit.Assert; + +import junit.framework.TestCase; + +public class ExecutorTest extends TestCase +{ + public void testBuildClasspath() throws MalformedURLException { + String basename = "home/test/dir with space/mylib.jar"; + String pathname = new File("/", basename).getPath(); + if ( SystemUtils.IS_OS_WINDOWS ) + { + pathname = new File( File.listRoots()[0], basename ).getPath(); + } + URL[] urls = new URL[] { new File(pathname).toURI().toURL() }; + URLClassLoader mockedClassLoader = new URLClassLoader( urls ); + + StringBuilder classpath = new StringBuilder(); + Executor.buildClasspath(classpath, mockedClassLoader); + Assert.assertEquals( pathname + File.pathSeparator, classpath.toString() ); + } +}