NIFI-2619: Added unit test showing bugs, Added logic to ClassLoaderUtils to trim module paths and accept URLs

Signed-off-by: Yolanda M. Davis <ymdavis@apache.org>

This closes #907
This commit is contained in:
Matt Burgess 2016-08-22 11:09:14 -04:00 committed by Yolanda M. Davis
parent 7884d09948
commit 7123a1a276
2 changed files with 52 additions and 23 deletions

View File

@ -16,50 +16,67 @@
*/ */
package org.apache.nifi.util.file.classloader; package org.apache.nifi.util.file.classloader;
import org.apache.commons.lang3.StringUtils;
import java.io.File; import java.io.File;
import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
public class ClassLoaderUtils { public class ClassLoaderUtils {
public static ClassLoader getCustomClassLoader(String modulePath, ClassLoader parentClassLoader, FilenameFilter filenameFilter) throws MalformedURLException { public static ClassLoader getCustomClassLoader(String modulePath, ClassLoader parentClassLoader, FilenameFilter filenameFilter) throws MalformedURLException {
String[] modules = modulePath != null? modulePath.split(",") : null; // Split and trim the module path(s)
URL[] classpaths = getURLsForClasspath(modules,filenameFilter); List<String> modules = (modulePath == null)
return createModuleClassLoader(classpaths,parentClassLoader); ? null
: Arrays.stream(modulePath.split(",")).filter(StringUtils::isNotBlank).map(String::trim).collect(Collectors.toList());
URL[] classpaths = getURLsForClasspath(modules, filenameFilter);
return createModuleClassLoader(classpaths, parentClassLoader);
} }
protected static URL[] getURLsForClasspath(String[] modulePaths, FilenameFilter filenameFilter) throws MalformedURLException { protected static URL[] getURLsForClasspath(List<String> modulePaths, FilenameFilter filenameFilter) throws MalformedURLException {
List<URL> additionalClasspath = new LinkedList<>(); List<URL> additionalClasspath = new LinkedList<>();
if (modulePaths != null) { if (modulePaths != null) {
for (String modulePathString : modulePaths) { for (String modulePathString : modulePaths) {
File modulePath = new File(modulePathString); // If the path is already a URL, just add it (but don't check if it exists, too expensive and subject to network availability)
boolean isUrl = true;
try {
additionalClasspath.add(new URL(modulePathString));
} catch (MalformedURLException mue) {
isUrl = false;
}
if (!isUrl) {
File modulePath = new File(modulePathString);
if (modulePath.exists()) { if (modulePath.exists()) {
additionalClasspath.add(modulePath.toURI().toURL()); additionalClasspath.add(modulePath.toURI().toURL());
if (modulePath.isDirectory()) { if (modulePath.isDirectory()) {
File[] files = modulePath.listFiles(filenameFilter); File[] files = modulePath.listFiles(filenameFilter);
if (files != null) { if (files != null) {
for (File jarFile : files) { for (File jarFile : files) {
additionalClasspath.add(jarFile.toURI().toURL()); additionalClasspath.add(jarFile.toURI().toURL());
}
} }
} }
} else {
throw new MalformedURLException("Path specified does not exist");
} }
} else {
throw new MalformedURLException("Path specified does not exist");
} }
} }
} }
return additionalClasspath.toArray(new URL[additionalClasspath.size()]); return additionalClasspath.toArray(new URL[additionalClasspath.size()]);
} }
protected static ClassLoader createModuleClassLoader(URL[] modules,ClassLoader parentClassLoader) { protected static ClassLoader createModuleClassLoader(URL[] modules, ClassLoader parentClassLoader) {
return new URLClassLoader(modules, parentClassLoader); return new URLClassLoader(modules, parentClassLoader);
} }

View File

@ -16,12 +16,12 @@
*/ */
package org.apache.nifi.util.file.classloader; package org.apache.nifi.util.file.classloader;
import java.io.File;
import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
@ -61,13 +61,25 @@ public class TestClassLoaderUtils {
fail("exception did not occur, path should not exist"); fail("exception did not occur, path should not exist");
} }
protected FilenameFilter getJarFilenameFilter(){ @Test
return new FilenameFilter() { public void testGetCustomClassLoaderWithMultipleLocations() throws Exception {
@Override final String jarFilePath = " src/test/resources/TestClassLoaderUtils/TestSuccess.jar, http://nifi.apache.org/Test.jar";
public boolean accept(File dir, String name) { assertNotNull(ClassLoaderUtils.getCustomClassLoader(jarFilePath, this.getClass().getClassLoader(), getJarFilenameFilter()));
return (name != null && name.endsWith(".jar"));
}
};
} }
@Test
public void testGetCustomClassLoaderWithEmptyLocations() throws Exception {
String jarFilePath = "";
assertNotNull(ClassLoaderUtils.getCustomClassLoader(jarFilePath, this.getClass().getClassLoader(), getJarFilenameFilter()));
jarFilePath = ",";
assertNotNull(ClassLoaderUtils.getCustomClassLoader(jarFilePath, this.getClass().getClassLoader(), getJarFilenameFilter()));
jarFilePath = ",src/test/resources/TestClassLoaderUtils/TestSuccess.jar, ";
assertNotNull(ClassLoaderUtils.getCustomClassLoader(jarFilePath, this.getClass().getClassLoader(), getJarFilenameFilter()));
}
protected FilenameFilter getJarFilenameFilter(){
return (dir, name) -> name != null && name.endsWith(".jar");
}
} }