Skip to content

Commit

Permalink
[DROOLS-7608] fix KieProject lookup on classpath for EAP 7.4.15 VFS
Browse files Browse the repository at this point in the history
  • Loading branch information
mariofusco committed Feb 15, 2024
1 parent 5b13798 commit 15c3463
Showing 1 changed file with 62 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import java.net.URI;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
Expand Down Expand Up @@ -427,11 +429,9 @@ public static String fixURLFromKProjectPath(URL url) {
}

try {
urlPath = URLDecoder.decode( urlPath,
"UTF-8" );
urlPath = URLDecoder.decode( urlPath, "UTF-8" );
} catch ( UnsupportedEncodingException e ) {
throw new IllegalArgumentException( "Error decoding URL (" + url + ") using UTF-8",
e );
throw new IllegalArgumentException( "Error decoding URL (" + url + ") using UTF-8", e );
}

log.debug("KieModule URL type=" + urlType + " url=" + urlPath);
Expand All @@ -440,41 +440,50 @@ public static String fixURLFromKProjectPath(URL url) {
}

private static String getPathForVFS(URL url) {
Method m = null;
Method vfsGetPhysicalFileMethod = null;
try {
m = Class.forName("org.jboss.vfs.VirtualFile").getMethod("getPhysicalFile");
vfsGetPhysicalFileMethod = Class.forName("org.jboss.vfs.VirtualFile").getMethod("getPhysicalFile");
} catch (Exception e) {
try {
// Try to retrieve the VirtualFile class also on TCCL
m = Class.forName("org.jboss.vfs.VirtualFile", true, Thread.currentThread().getContextClassLoader()).getMethod("getPhysicalFile");
vfsGetPhysicalFileMethod = Class.forName("org.jboss.vfs.VirtualFile", true, Thread.currentThread().getContextClassLoader()).getMethod("getPhysicalFile");
} catch (Exception e1) {
// VirtualFile is not available on the classpath - ignore
log.warn( "Found virtual file " + url + " but org.jboss.vfs.VirtualFile is not available on the classpath" );
}
}
Method m2 = null;

Class vfsClass = null;
Method vfsGetChildMethod = null;
boolean useTccl = false;

try {
m2 = Class.forName("org.jboss.vfs.VFS").getMethod("getChild", URI.class);
vfsClass = lookupVfsClass("org.jboss.vfs.VFS", useTccl);
vfsGetChildMethod = vfsClass.getMethod("getChild", URI.class);
} catch (Exception e) {
try {
// Try to retrieve the org.jboss.vfs.VFS class also on TCCL
m2 = Class.forName("org.jboss.vfs.VFS", true, Thread.currentThread().getContextClassLoader()).getMethod("getChild", URI.class);
useTccl = true;
vfsClass = lookupVfsClass("org.jboss.vfs.VFS", useTccl);
vfsGetChildMethod = vfsClass.getMethod("getChild", URI.class);
} catch (Exception e1) {
// VFS is not available on the classpath - ignore
log.warn( "Found virtual file " + url + " but org.jboss.vfs.VFS is not available on the classpath" );
}
}

if (m == null || m2 == null) {
if (vfsGetPhysicalFileMethod == null || vfsGetChildMethod == null) {
return url.getPath();
}

String path = null;
Object virtualFile = null;
try {
File f = (File)m.invoke( m2.invoke(null, url.toURI()) );
virtualFile = vfsGetChildMethod.invoke( null, url.toURI() );
File f = (File) vfsGetPhysicalFileMethod.invoke( virtualFile );
path = f.getPath();
} catch (Exception e) {
log.error( "Error when reading virtual file from " + url.toString(), e );
log.error( "Error when reading virtual file from " + url, e );
}

if (path == null) {
Expand All @@ -486,28 +495,56 @@ private static String getPathForVFS(URL url) {
return path;
}

int kModulePos = urlString.length() - ("/" + KieModuleModelImpl.KMODULE_JAR_PATH).length();
boolean isInJar = urlString.substring(kModulePos - 4, kModulePos).equals(".jar");

try {
if (isInJar && path.contains("contents" + File.separator)) {
String jarName = urlString.substring(0, kModulePos);
jarName = jarName.substring(jarName.lastIndexOf('/')+1);
String jarFolderPath = path.substring( 0, path.length() - ("contents/" + KieModuleModelImpl.KMODULE_JAR_PATH).length() );
String jarPath = jarFolderPath + jarName;
path = new File(jarPath).exists() ? jarPath : jarFolderPath + "content";
} else if (path.endsWith(File.separator + KieModuleModelImpl.KMODULE_FILE_NAME)) {
path = path.substring( 0, path.length() - ("/" + KieModuleModelImpl.KMODULE_JAR_PATH).length() );
path = rewriteVFSPath(path, urlString);
if (!Files.exists(Paths.get(path))) {
// see https://issues.redhat.com/browse/DROOLS-7608
path = rewriteVFSPathAfter_7_4_15(vfsClass, virtualFile, useTccl);
}

log.info( "Virtual file physical path = " + path );
return path;
} catch (Exception e) {
log.error( "Error when reading virtual file from " + url.toString(), e );
log.error( "Error when reading virtual file from " + url, e );
}
return url.getPath();
}

private static String rewriteVFSPath(String path, String urlString) {
int kModulePos = urlString.length() - ("/" + KieModuleModelImpl.KMODULE_JAR_PATH).length();
boolean isInJar = urlString.substring(kModulePos - 4, kModulePos).equals(".jar");

if (isInJar && path.contains("contents" + File.separator)) {
String jarName = urlString.substring(0, kModulePos);
jarName = jarName.substring(jarName.lastIndexOf('/')+1);
String jarFolderPath = path.substring(0, path.length() - ("contents/" + KieModuleModelImpl.KMODULE_JAR_PATH).length() );
String jarPath = jarFolderPath + jarName;
return new File(jarPath).exists() ? jarPath : jarFolderPath + "content";
}
if (path.endsWith(File.separator + KieModuleModelImpl.KMODULE_FILE_NAME)) {
return path.substring(0, path.length() - ("/" + KieModuleModelImpl.KMODULE_JAR_PATH).length() );
}
return path;
}

private static String rewriteVFSPathAfter_7_4_15(Class vfsClass, Object virtualFile, boolean useTccl) throws Exception {
Method vfsGetMountMethod = vfsClass.getDeclaredMethod("getMount", lookupVfsClass("org.jboss.vfs.VirtualFile", useTccl));
vfsGetMountMethod.setAccessible(true);
Object mount = vfsGetMountMethod.invoke(null, virtualFile);

Method mountGetFileSystemMethod = lookupVfsClass("org.jboss.vfs.VFS$Mount", useTccl).getDeclaredMethod("getFileSystem");
mountGetFileSystemMethod.setAccessible(true);
Object fileSystem = mountGetFileSystemMethod.invoke(mount);

Method fileSystemGetMountSourceMethod = lookupVfsClass("org.jboss.vfs.spi.FileSystem", useTccl).getMethod("getMountSource");
File mountSource = (File) fileSystemGetMountSourceMethod.invoke(fileSystem);
return mountSource.getPath();
}

private static Class<?> lookupVfsClass(String classname, boolean useTccl) throws ClassNotFoundException {
return useTccl ? Class.forName(classname, true, Thread.currentThread().getContextClassLoader()) : Class.forName(classname);
}

public InternalKieModule getKieModuleForKBase(String kBaseName) {
return this.kJarFromKBaseName.get( kBaseName );
}
Expand Down

0 comments on commit 15c3463

Please sign in to comment.