mirror of https://github.com/apache/nifi.git
NIFI-10004: Allow loading .class files that are relative to the NAR directory, in addition to the .jar / .nar files
NIFI-10004: When determining classname from a file, consider File.separator instead of just / Signed-off-by: Matthew Burgess <mattyb149@apache.org> This closes #6026
This commit is contained in:
parent
c3829e2198
commit
9311188785
|
@ -74,4 +74,18 @@
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.rat</groupId>
|
||||||
|
<artifactId>apache-rat-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<excludes combine.children="append">
|
||||||
|
<exclude>src/test/resources/FakeBootstrap.class</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
|
@ -158,6 +158,8 @@ public class StatelessBootstrap {
|
||||||
filesAllowed.add(file.getName());
|
filesAllowed.add(file.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
findClassNamesInDirectory(narDirectory, narDirectory, classesAllowed, filesAllowed);
|
||||||
|
|
||||||
final File java11Directory = new File(narDirectory, "java11");
|
final File java11Directory = new File(narDirectory, "java11");
|
||||||
final File[] java11DirectoryFiles = java11Directory.listFiles();
|
final File[] java11DirectoryFiles = java11Directory.listFiles();
|
||||||
if (java11DirectoryFiles != null) {
|
if (java11DirectoryFiles != null) {
|
||||||
|
@ -174,7 +176,7 @@ public class StatelessBootstrap {
|
||||||
javaHomeFilenames.add(file.getName());
|
javaHomeFilenames.add(file.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug("The following JAR files will be explicitly allowed to be loaded by Stateless Extensions ClassLoaders from parent {}: {}", parent, filesAllowed);
|
logger.debug("The following class/JAR files will be explicitly allowed to be loaded by Stateless Extensions ClassLoaders from parent {}: {}", parent, filesAllowed);
|
||||||
logger.debug("The following JAR/JMOD files from ${JAVA_HOME} will be explicitly allowed to be loaded by Stateless Extensions ClassLoaders from parent {}: {}", parent, javaHomeFilenames);
|
logger.debug("The following JAR/JMOD files from ${JAVA_HOME} will be explicitly allowed to be loaded by Stateless Extensions ClassLoaders from parent {}: {}", parent, javaHomeFilenames);
|
||||||
logger.debug("The final list of classes allowed to be loaded by Stateless Extension ClassLoaders from parent {}: {}", parent, classesAllowed);
|
logger.debug("The final list of classes allowed to be loaded by Stateless Extension ClassLoaders from parent {}: {}", parent, classesAllowed);
|
||||||
|
|
||||||
|
@ -258,6 +260,36 @@ public class StatelessBootstrap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void findClassNamesInDirectory(final File file, final File baseDirectory, final Set<String> classNames, final Set<String> fileNames) {
|
||||||
|
if (file.isDirectory()) {
|
||||||
|
final File[] children = file.listFiles();
|
||||||
|
if (children != null) {
|
||||||
|
for (final File child : children) {
|
||||||
|
findClassNamesInDirectory(child, baseDirectory, classNames, fileNames);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String filename = file.getName();
|
||||||
|
if (filename.endsWith(".class")) {
|
||||||
|
final String absolutePath = file.getAbsolutePath();
|
||||||
|
final String baseDirectoryPath = baseDirectory.getAbsolutePath();
|
||||||
|
if (!absolutePath.startsWith(baseDirectoryPath)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final File relativeFile = baseDirectory.toPath().relativize(file.toPath()).toFile();
|
||||||
|
final String relativePath = relativeFile.getPath();
|
||||||
|
|
||||||
|
final int lastIndex = relativePath.lastIndexOf(".class");
|
||||||
|
final String className = relativePath.substring(0, lastIndex).replace(File.separator, ".");
|
||||||
|
classNames.add(className);
|
||||||
|
fileNames.add(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void findClassesInJmod(final File file, final Set<String> classNames) throws IOException {
|
private static void findClassesInJmod(final File file, final Set<String> classNames) throws IOException {
|
||||||
if (!file.getName().endsWith(".jmod") || !file.isFile() || !file.exists()) {
|
if (!file.getName().endsWith(".jmod") || !file.isFile() || !file.exists()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* 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.nifi.stateless.bootstrap;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
public class TestStatelessBootstrap {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllowsClassFiles() {
|
||||||
|
final File libDir = new File("src/test/resources/test-lib");
|
||||||
|
|
||||||
|
final Set<String> classNames = new HashSet<>();
|
||||||
|
final Set<String> fileNames = new HashSet<>();
|
||||||
|
StatelessBootstrap.findClassNamesInDirectory(libDir, libDir, classNames, fileNames);
|
||||||
|
|
||||||
|
assertEquals(1, classNames.size());
|
||||||
|
assertEquals(1, fileNames.size());
|
||||||
|
assertTrue(classNames.contains("org.apache.nifi.stateless.FakeBootstrap"));
|
||||||
|
assertTrue(fileNames.contains("FakeBootstrap.class"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
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.
|
Loading…
Reference in New Issue