diff --git a/headless-services/commons/commons-gradle/src/main/java/org/springframework/ide/vscode/commons/gradle/GradleProjectClasspath.java b/headless-services/commons/commons-gradle/src/main/java/org/springframework/ide/vscode/commons/gradle/GradleProjectClasspath.java index 8668eb82c..f35616c32 100644 --- a/headless-services/commons/commons-gradle/src/main/java/org/springframework/ide/vscode/commons/gradle/GradleProjectClasspath.java +++ b/headless-services/commons/commons-gradle/src/main/java/org/springframework/ide/vscode/commons/gradle/GradleProjectClasspath.java @@ -22,7 +22,7 @@ import org.gradle.tooling.model.eclipse.EclipseProject; import org.gradle.tooling.model.eclipse.EclipseProjectDependency; import org.gradle.tooling.model.eclipse.EclipseSourceDirectory; import org.springframework.ide.vscode.commons.java.IClasspath; -import org.springframework.ide.vscode.commons.languageserver.java.JavaUtils; +import org.springframework.ide.vscode.commons.java.JavaUtils; import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath; import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/BasicJandexIndex.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/BasicJandexIndex.java index 193b17792..133908cad 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/BasicJandexIndex.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/BasicJandexIndex.java @@ -11,32 +11,21 @@ package org.springframework.ide.vscode.commons.jandex; import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; -import java.util.stream.Stream; import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; -import org.jboss.jandex.IndexReader; import org.jboss.jandex.IndexView; -import org.jboss.jandex.Indexer; -import org.jboss.jandex.JarIndexer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.ide.vscode.commons.java.IClasspath; +import org.springframework.ide.vscode.commons.java.IClasspathUtil; +import org.springframework.ide.vscode.commons.java.IJavaModuleData; import org.springframework.ide.vscode.commons.util.FuzzyMatcher; -import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import reactor.core.publisher.Flux; import reactor.core.scheduler.Schedulers; @@ -71,212 +60,106 @@ public class BasicJandexIndex { return folder; } - private Map>> index; + private ImmutableList modules; - private Map>>> knownTypes; - - private Map>> knownPackages; - - private BasicJandexIndex[] baseIndex; - - BasicJandexIndex(Collection classpathEntries, IndexFileFinder indexFileFinder, - BasicJandexIndex... baseIndex) { - this.baseIndex = baseIndex; - this.index = new ConcurrentHashMap<>(); - this.knownTypes = new HashMap<>(); - this.knownPackages = new HashMap<>(); - classpathEntries.forEach(file -> { - index.put(file, /*Suppliers.synchronizedSupplier(*/Suppliers.memoize(() -> createIndex(file, indexFileFinder))/*)*/); - knownTypes.put(file, Suppliers.memoize(() -> getKnownTypesStream(file).collect(Collectors.toList()))); - knownPackages.put(file, Suppliers.memoize(() -> getKnownPackages(file).collect(Collectors.toList()))); - }); - } - - private Optional createIndex(File file, IndexFileFinder indexFileFinder) { - if (file != null && file.isFile() && file.getName().endsWith(".jar")) { - return indexJar(file, indexFileFinder); - } else if (file != null && file.isDirectory()) { - return indexFolder(file); - } else { - return Optional.empty(); + BasicJandexIndex(IClasspath classpath, IndexFileFinder indexFileFinder) { + ImmutableList.Builder builder = ImmutableList.builder(); + try { + classpath.getClasspathEntries().forEach(cpe -> { + File binaryLocation = IClasspathUtil.binaryLocation(cpe); + builder.addAll(IndexRoutines.fromCPE(cpe, indexFileFinder.findIndexFile(binaryLocation))); + }); + } catch (Exception e) { + log.error("", e); } + this.modules = builder.build(); } - private static Optional indexFolder(File folder) { - Indexer indexer = new Indexer(); - for (Iterator itr = com.google.common.io.Files.fileTreeTraverser().breadthFirstTraversal(folder) - .iterator(); itr.hasNext();) { - File file = itr.next(); - if (file.isFile() && file.getName().endsWith(".class")) { - try { - final InputStream stream = new FileInputStream(file); - try { - indexer.index(stream); - } finally { - try { - stream.close(); - } catch (Exception ignore) { - } - } - } catch (Exception e) { - log.error("Failed to index file " + file, e); + Tuple2 getClassByName(DotName fqName) { + for (ModuleJandexIndex m : modules) { + IndexView indexView = m.getIndex().get(); + if (indexView != null) { + ClassInfo info = indexView.getClassByName(fqName); + if (info != null) { + return Tuples.of(m, info); } } } - return Optional.of(indexer.complete()); + return null; } - private static Optional indexJar(File file, IndexFileFinder indexFileFinder) { - File indexFile = indexFileFinder.findIndexFile(file); - if (indexFile != null) { - try { - if (!indexFile.getParentFile().exists()) { - indexFile.getParentFile().mkdirs(); + public IJavaModuleData findClasspathResourceForType(String fqName) { + Tuple2 match = getClassByName(DotName.createSimple(fqName)); + return match == null ? null : match.getT1(); + } + + private Collection getKnownPackages(ModuleJandexIndex module) { + ImmutableSet.Builder builder = ImmutableSet.builder(); + IndexView indexView = module.getIndex().get(); + if (indexView != null) { + indexView.getKnownClasses(); + Collection knownClasses = indexView.getKnownClasses(); + if (knownClasses != null) { + for (ClassInfo info : knownClasses) { + String name = info.name().toString(); + String pkg = name.substring(0, name.lastIndexOf('.')); + builder.add(pkg); } - if (indexFile.createNewFile()) { - try { - return Optional.of(JarIndexer.createJarIndex(file, new Indexer(), indexFile, false, false, - false, System.out, System.err).getIndex()); - } catch (IOException e) { - log.error("Failed to index '" + file + "'", e); - } - } else { - try { - return Optional.of(new IndexReader(new FileInputStream(indexFile)).read()); - } catch (IOException e) { - log.error("Failed to read index file '" + indexFile + "'. Creating new index file.", e); - if (indexFile.delete()) { - return indexJar(file, indexFileFinder); - } else { - log.error("Failed to read index file '" + indexFile); - } - } - } - } catch (IOException e) { - log.error("Unable to create index file '" + indexFile + "'", e); - } - } else { - try { - return Optional.of(JarIndexer - .createJarIndex(file, new Indexer(), file.canWrite(), file.getParentFile().canWrite(), false) - .getIndex()); - } catch (IOException e) { - log.error("Failed to index '" + file + "'", e); } } - return Optional.empty(); + return builder.build(); } - Tuple2 getClassByName(DotName fqName) { - // First look for type in the base index array - return (baseIndex == null ? Stream.>empty() - : Arrays.stream( - baseIndex) - .filter( - jandexIndex -> jandexIndex != null) - .map(jandexIndex -> jandexIndex.getClassByName(fqName))).filter(type -> type != null) - .findFirst() - // If not found look at indices owned by this - // JandexIndex instance - .orElseGet(() -> streamOfIndices() - .map(e -> Tuples.of(e.getT1(), Optional.ofNullable(e.getT2().getClassByName(fqName)))) - .filter(t -> t.getT2().isPresent()) - .map(e -> Tuples.of(e.getT1(), e.getT2().get())).findFirst() - .orElse(null)); - - } - - private Optional> findMatch(DotName fqName) { - return (baseIndex == null ? Stream.>>empty() - : Arrays.stream( - baseIndex) - .filter( - jandexIndex -> jandexIndex != null) - .map(jandexIndex -> jandexIndex.findMatch(fqName))).filter(o -> o.isPresent()) - .findFirst() - // If not found look at indices owned by this - // JandexIndex instance - .orElseGet(() -> streamOfIndices() - .map(e -> { - IndexView view = e.getT2(); - ClassInfo info = view.getClassByName(fqName); - return Tuples.of(e.getT1(), Optional.ofNullable(info)); -// return Tuples.of(e.getT1(), Optional.ofNullable(e.getT2().getClassByName(fqName))); - }) - .filter(t -> t.getT2().isPresent()) - .map(e -> Tuples.of(e.getT1(), e.getT2().get())).findFirst()); - } - - public Optional findClasspathResourceForType(String fqName) { - Optional> match = findMatch(DotName.createSimple(fqName)); - return Optional.ofNullable(match.isPresent() ? match.get().getT1() : null); - } - - private Stream> streamOfIndices() { - return index.entrySet().parallelStream().map(e -> Tuples.of(e.getKey(), e.getValue().get())) - .filter(t -> t.getT2().isPresent()).map(t -> Tuples.of(t.getT1(), t.getT2().get())); - } - - private Stream> getKnownTypesStream(File file) { - Optional indexView = index.get(file).get(); - if (indexView.isPresent()) { - return indexView.get().getKnownClasses().parallelStream() - .map(info -> Tuples.of(info.name().toString(), file, info)); + private List> getKnownTypeTuples(ModuleJandexIndex module) { + ImmutableList.Builder> builder = ImmutableList.builder(); + IndexView indexView = module.getIndex().get(); + if (indexView != null) { + Collection knownClasses = indexView.getKnownClasses(); + if (knownClasses != null) { + for (ClassInfo info : knownClasses) { + builder.add(Tuples.of(module, info)); + } + } } - return Stream.empty(); + return builder.build(); } - private final Stream getKnownPackages(File file) { - Optional indexView = index.get(file).get(); - if (indexView.isPresent()) { - return indexView.get().getKnownClasses().parallelStream().map(info -> { - String name = info.name().toString(); - return name.substring(0, name.lastIndexOf('.')); - }).distinct(); + private List> getAllKnownSubclasses(ModuleJandexIndex module, DotName name, boolean isInterface) { + ImmutableList.Builder> builder = ImmutableList.builder(); + IndexView indexView = module.getIndex().get(); + if (indexView != null) { + Collection subTypes = isInterface ? indexView.getAllKnownImplementors(name) : indexView.getAllKnownSubclasses(name); + if (subTypes != null) { + for (ClassInfo info : subTypes) { + builder.add(Tuples.of(module, info)); + } + } } - return Stream.empty(); + return builder.build(); } - Flux> fuzzySearchTypes(String searchTerm) { - Flux> flux = Flux.fromIterable(knownTypes.values()).publishOn(Schedulers.parallel()) - .flatMap(s -> Flux.fromIterable(s.get())) - .map(t -> Tuples.of(t.getT2(), t.getT3(), FuzzyMatcher.matchScore(searchTerm, t.getT1()))) - .filter(t -> t.getT3() != 0.0); - if (baseIndex == null) { - return flux; - } else { - return Flux.merge(flux, - Flux.fromArray(baseIndex).flatMap(index -> index.fuzzySearchTypes(searchTerm))); - } + Flux> fuzzySearchTypes(String searchTerm) { + Flux> flux = Flux.fromIterable(modules).publishOn(Schedulers.parallel()) + .flatMap(m -> Flux.fromIterable(getKnownTypeTuples(m))) + .map(t -> Tuples.of(t.getT1(), t.getT2(), FuzzyMatcher.matchScore(searchTerm, t.getT2().name().toString()))) + .filter(t -> t.getT3() != 0.0); + + return flux; } public Flux> fuzzySearchPackages(String searchTerm) { - Flux> flux = Flux.fromIterable(knownPackages.values()).publishOn(Schedulers.parallel()) - .flatMap(s -> Flux.fromIterable(s.get())) - .map(pkg -> Tuples.of(pkg, FuzzyMatcher.matchScore(searchTerm, pkg))).filter(t -> t.getT2() != 0.0); - if (baseIndex == null) { - return flux; - } else { - return Flux.merge(flux, Flux.fromArray(baseIndex).flatMap(index -> index.fuzzySearchPackages(searchTerm))); - } + Flux> flux = Flux.fromIterable(modules).publishOn(Schedulers.parallel()) + .flatMap(m -> Flux.fromIterable(getKnownPackages(m))) + .map(pkg -> Tuples.of(pkg, FuzzyMatcher.matchScore(searchTerm, pkg))) + .filter(t -> t.getT2() != 0.0); + + return flux; } - Flux> allSubtypesOf(DotName name, boolean isInterface) { - Flux> flux = Flux.fromIterable(index.keySet()).publishOn(Schedulers.parallel()).flatMap(file -> { - Optional optional = index.get(file).get(); - if (optional.isPresent()) { - return Flux - .fromIterable(isInterface ? optional.get().getAllKnownImplementors(name) - : optional.get().getAllKnownSubclasses(name)) - .publishOn(Schedulers.parallel()).map(info -> Tuples.of(file, info)); - } else { - return Flux.empty(); - } - }); - if (baseIndex == null) { - return flux; - } else { - return Flux.merge(flux, Flux.fromArray(baseIndex).flatMap(index -> index.allSubtypesOf(name, isInterface))); - } + Flux> allSubtypesOf(DotName name, boolean isInterface) { + Flux> flux = Flux.fromIterable(modules).publishOn(Schedulers.parallel()) + .flatMap(module -> Flux.fromIterable(getAllKnownSubclasses(module, name, isInterface))); + + return flux; } } diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/IndexRoutines.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/IndexRoutines.java new file mode 100644 index 000000000..497b00940 --- /dev/null +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/IndexRoutines.java @@ -0,0 +1,223 @@ +/******************************************************************************* + * Copyright (c) 2018 Pivotal, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.commons.jandex; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Iterator; + +import org.jboss.jandex.Index; +import org.jboss.jandex.IndexReader; +import org.jboss.jandex.IndexView; +import org.jboss.jandex.IndexWriter; +import org.jboss.jandex.Indexer; +import org.jboss.jandex.JarIndexer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.ide.vscode.commons.java.IClasspathUtil; +import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; + +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; +import com.google.common.collect.ImmutableList; + +public class IndexRoutines { + + private static final Logger log = LoggerFactory.getLogger(IndexRoutines.class); + + private static final URI JRT_URI = URI.create("jrt:/"); + + static ImmutableList fromClasspathBinaryEntry(File file, File indexFile) { + ImmutableList.Builder builder = ImmutableList.builder(); + if (file != null) { + if (file.isFile()) { + if (file.getName().endsWith("jrt-fs.jar")) { + builder.addAll(IndexRoutines.fromJrtFs(file, indexFile)); + } else if (file.getName().endsWith(".jar")) { + builder.add(IndexRoutines.fromJar(file, indexFile)); + } + } else if (file.isDirectory()) { + builder.add(IndexRoutines.fromFolder(file)); + } + } + return builder.build(); + } + + static ImmutableList fromCPE(CPE cpe, File indexFile) { + File binaryLocation = IClasspathUtil.binaryLocation(cpe); + if (cpe.isSystem()) { + return JandexSystemLibsIndex.getInstance().index(binaryLocation.toPath()); + } else { + return IndexRoutines.fromClasspathBinaryEntry(binaryLocation, indexFile); + } + } + + private static ModuleJandexIndex fromJar(File file, File indexFile) { + return new ModuleJandexIndex(file, null, Suppliers.memoize(() -> indexJar(file, indexFile))); + } + + private static ModuleJandexIndex fromFolder(File folder) { + return new ModuleJandexIndex(folder, null, Suppliers.memoize(() -> indexFolder(folder))); + } + + private static ModuleJandexIndex fromModule(File container, Path modulePath, File indexFolder) { + String module = modulePath.getFileName().toString(); + File indexFile = new File(indexFolder, module + ".jdx"); + return new ModuleJandexIndex(container, module, Suppliers.memoize(() -> indexModule(modulePath, indexFile))); + } + + private static ImmutableList fromJrtFs(File jrtFsJar, File indexFolder) { + // little hack for backwards compatibility + if (indexFolder.isFile()) { + indexFolder.delete(); + } + + ImmutableList.Builder builder = ImmutableList.builder(); + String javaVersion = System.getProperty("java.version"); //$NON-NLS-1$ + FileSystem fs = null; + Path jdkHome = jrtFsJar.toPath().getParent().getParent(); + try { + if (javaVersion != null && javaVersion.startsWith("1.8")) { //$NON-NLS-1$ + URLClassLoader loader = new URLClassLoader(new URL[] { jrtFsJar.toURI().toURL() }); + HashMap env = new HashMap<>(); + fs = FileSystems.newFileSystem(JRT_URI, env, loader); + } else { + HashMap env = new HashMap<>(); + env.put("java.home", jdkHome.toString()); //$NON-NLS-1$ + fs = FileSystems.newFileSystem(JRT_URI, env); + } + if (fs != null) { + Files.list(fs.getPath("/modules")).filter(Files::isDirectory).forEach(path -> builder.add(fromModule(jrtFsJar, path, indexFolder))); +// builder.add(fromModule(jrtFsJar, fs.getPath("modules", "java.base"), indexFolder)); + } + } catch (IOException e) { + log.error("", e); + } + return builder.build(); + } + + private static IndexView indexModule(Path modulePath, File indexFile) { + return createOrLoadIndex(indexFile, () -> createModuleIndex(modulePath, indexFile)); + } + + private static IndexView createModuleIndex(Path modulePath, File indexFile) { + FileOutputStream out = null; + try { + out = new FileOutputStream(indexFile); + Indexer indexer = new Indexer(); + Files.walk(modulePath).forEach(entry -> { + if (entry.getFileName().toString().endsWith(".class")) { + try { + final InputStream stream = Files.newInputStream(entry); + try { + indexer.index(stream); + } finally { + try { + stream.close(); + } catch (Exception ignore) { + } + } + } catch (Exception e) { + log.debug("", e); + } + } + }); + + IndexWriter writer = new IndexWriter(out); + Index index = indexer.complete(); + writer.write(index); + return index; + } catch (IOException e) { + log.error("", e); + } finally { + if (out != null) { + try { + out.close(); + } catch (Exception ignore) { + } + } + } + return null; + } + + private static IndexView indexFolder(File folder) { + Indexer indexer = new Indexer(); + for (Iterator itr = com.google.common.io.Files.fileTreeTraverser().breadthFirstTraversal(folder) + .iterator(); itr.hasNext();) { + File file = itr.next(); + if (file.isFile() && file.getName().endsWith(".class")) { + try { + final InputStream stream = new FileInputStream(file); + try { + indexer.index(stream); + } finally { + try { + stream.close(); + } catch (Exception ignore) { + } + } + } catch (Exception e) { + log.error("Failed to index file " + file, e); + } + } + } + return indexer.complete(); + } + + private static IndexView indexJar(File file, File indexFile) { + return createOrLoadIndex(indexFile, () -> createJarIndex(indexFile, file)); + } + + private static IndexView createJarIndex(File indexFile, File jarFile) { + try { + return JarIndexer.createJarIndex(jarFile, new Indexer(), indexFile, false, false, + false, System.out, System.err).getIndex(); + } catch (Exception e) { + log.error("Failed to index '" + jarFile + "'", e); + return null; + } + } + + private static IndexView createOrLoadIndex(File indexFile, Supplier indexCreator) { + if (indexFile != null) { + if (!indexFile.getParentFile().exists()) { + indexFile.getParentFile().mkdirs(); + } + if (!indexFile.exists()) { + return indexCreator.get(); + } else { + try { + return new IndexReader(new FileInputStream(indexFile)).read(); + } catch (IOException e) { + log.error("Failed to read index file '" + indexFile + "'. Creating new index file.", e); + if (indexFile.delete()) { + return createOrLoadIndex(indexFile, indexCreator); + } else { + log.error("Failed to read index file '" + indexFile); + } + } + } + } + return null; + } + +} diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/JandexClasspath.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/JandexClasspath.java index 67bbb4b63..639b65b32 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/JandexClasspath.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/JandexClasspath.java @@ -15,7 +15,6 @@ import java.io.IOException; import java.net.URL; import java.nio.file.Files; import java.util.Arrays; -import java.util.Collection; import java.util.HashSet; import java.util.LinkedList; import java.util.List; @@ -31,6 +30,7 @@ import org.springframework.ide.vscode.commons.jandex.JandexIndex.JavadocProvider import org.springframework.ide.vscode.commons.java.ClasspathIndex; import org.springframework.ide.vscode.commons.java.IClasspath; import org.springframework.ide.vscode.commons.java.IClasspathUtil; +import org.springframework.ide.vscode.commons.java.IJavaModuleData; import org.springframework.ide.vscode.commons.java.IType; import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath; import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; @@ -77,13 +77,7 @@ public final class JandexClasspath implements ClasspathIndex { protected JandexIndex createIndex() { log.info("Creating JandexIndex for "+classpath.getName()); attachFolderListeners(); - Collection classpathEntries = ImmutableList.of(); - try { - classpathEntries = IClasspathUtil.getBinaryRoots(classpath, (cpe) -> !cpe.isSystem()); - } catch (Exception e) { - log.error("Cannot obtain binary root from classpath entries for " + classpath.getName(), e); - } - return new JandexIndex(classpathEntries, jarFile -> findIndexFile(jarFile), javadocProviderFactory, getBaseIndices()); + return new JandexIndex(classpath, jarFile -> findIndexFile(jarFile), javadocProviderFactory); } private Disposable.Composite subscriptions = Disposables.composite(); @@ -115,10 +109,6 @@ public final class JandexClasspath implements ClasspathIndex { return cpe == null ? Optional.empty() : Optional.ofNullable(cpe.getSourceContainerUrl()); } - protected BasicJandexIndex[] getBaseIndices() { - return JandexSystemLibsIndex.getInstance().fromJars(IClasspathUtil.getBinaryRoots(classpath, CPE::isSystem)); - } - @Override public IType findType(String fqName) { return javaIndex.get().findType(fqName); @@ -152,7 +142,7 @@ public final class JandexClasspath implements ClasspathIndex { } @Override - public Optional findClasspathResourceContainer(String fqName) { + public IJavaModuleData findClasspathResourceContainer(String fqName) { return javaIndex.get().findClasspathResourceForType(fqName); } diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/JandexIndex.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/JandexIndex.java index cbbf6db29..726794579 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/JandexIndex.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/JandexIndex.java @@ -12,7 +12,6 @@ package org.springframework.ide.vscode.commons.jandex; import java.io.File; -import java.util.Collection; import java.util.concurrent.ExecutionException; import java.util.function.Predicate; @@ -20,6 +19,8 @@ import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.ide.vscode.commons.java.IClasspath; +import org.springframework.ide.vscode.commons.java.IJavaModuleData; import org.springframework.ide.vscode.commons.java.IJavadocProvider; import org.springframework.ide.vscode.commons.java.IType; @@ -51,21 +52,22 @@ public class JandexIndex extends BasicJandexIndex { return javadocProviderFactory; } - public JandexIndex(Collection classpathEntries, IndexFileFinder indexFileFinder, - JavadocProviderFactory javadocProviderFactory, BasicJandexIndex... baseIndex) { - super(classpathEntries, indexFileFinder, baseIndex); + public JandexIndex(IClasspath classpath, IndexFileFinder indexFileFinder, + JavadocProviderFactory javadocProviderFactory) { + super(classpath, indexFileFinder); this.javadocProviderFactory = javadocProviderFactory; } public IType findType(String fqName) { - return createType(getClassByName(DotName.createSimple(fqName))); + Tuple2 result = getClassByName(DotName.createSimple(fqName)); + return result == null ? null : createType(result); } - private IType createType(Tuple2 match) { + private IType createType(Tuple2 match) { if (match == null) { return null; } - File classpathResource = match.getT1(); + File classpathResource = match.getT1().getContainer(); IJavadocProvider javadocProvider = null; try { javadocProvider = javadocProvidersCache.get(classpathResource, () -> { diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/JandexSystemLibsIndex.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/JandexSystemLibsIndex.java index fbb9a27a9..0a6c208a3 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/JandexSystemLibsIndex.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/JandexSystemLibsIndex.java @@ -11,29 +11,22 @@ package org.springframework.ide.vscode.commons.jandex; import java.io.File; -import java.io.IOException; import java.nio.channels.IllegalSelectorException; -import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Objects; import java.util.concurrent.ExecutionException; -import java.util.regex.Pattern; -import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; -import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.common.collect.ImmutableList; import com.google.common.io.BaseEncoding; /** @@ -44,67 +37,34 @@ import com.google.common.io.BaseEncoding; */ public class JandexSystemLibsIndex { - private static final String DEFAULT_JAVA_VERSION = "1.8.0"; - - private static final Pattern JAVA_VERSION_PATTERN = Pattern.compile("^java version \"(.*)\"$"); +// private static final String DEFAULT_JAVA_VERSION = "1.8.0"; +// +// private static final Pattern JAVA_VERSION_PATTERN = Pattern.compile("^java version \"(.*)\"$"); public static final Logger log = LoggerFactory.getLogger(JandexSystemLibsIndex.class); private static final Supplier INSTANCE = Suppliers.memoize(() -> new JandexSystemLibsIndex()); - private Cache cache; + private LoadingCache> indexCache; private JandexSystemLibsIndex() { - this.cache = CacheBuilder.newBuilder().build(new CacheLoader() { + this.indexCache = CacheBuilder.newBuilder().build(new CacheLoader>() { @Override - public BasicJandexIndex load(Path key) throws Exception { - return createIndex(key); + public ImmutableList load(Path path) throws Exception { + File file = path.toFile(); + return IndexRoutines.fromClasspathBinaryEntry(file, findIndexFile(path)); } }); } - /** - * Retrieves or lazily creates Jandex Index for a folder containing system lib jars - * @param path the path containing jars - * @return Jandex Index of the jars contained in the folder - */ - public BasicJandexIndex index(Path path) { - try { - return cache.get(path, () -> createIndex(path)); - } catch (ExecutionException e) { - log.error("Failed to detrmine Jandex index for " + path, e); - return null; - } - } - - /** - * Retrieves Jandex Indexes appropriate for systm lib jars. One Jandex Index may contain all sys lib jars. - * @param jars system lib jars - * @return Jandex Indexs for jars - */ - public BasicJandexIndex[] fromJars(Collection jars) { - return jars.stream().map(jar -> jar.toPath().getParent()).distinct().map(folder -> index(folder)).filter(Objects::nonNull).toArray(BasicJandexIndex[]::new); - } - public static JandexSystemLibsIndex getInstance() { return INSTANCE.get(); } - private BasicJandexIndex createIndex(Path path) { - List jars = Collections.emptyList(); - try { - jars = Files.list(path).filter(p -> p.getFileName().toString().endsWith(".jar") && Files.isRegularFile(p)).map(p -> p.toFile()).collect(Collectors.toList()); - } catch (IOException e) { - // Shouldn't happen - there should at least be one jar file - log.error("Cannot list files in folder " + path, e); - } - return new BasicJandexIndex(jars, jarFile -> findIndexFile(jarFile)); - } - - private File findIndexFile(File jarFile) { - return Paths.get(System.getProperty("user.home"), ".sts4-jandex", folderNameforPath(jarFile.getParentFile().toString()), jarFile.getName() + ".jdx").toFile(); + private File findIndexFile(Path path) { + return Paths.get(System.getProperty("user.home"), ".sts4-jandex", folderNameforPath(path.getParent().toString()), path.getFileName() + ".jdx").toFile(); } private static String folderNameforPath(String path) { @@ -120,6 +80,15 @@ public class JandexSystemLibsIndex { } } + public ImmutableList index(Path path) { + try { + return indexCache.get(path); + } catch (ExecutionException e) { + log.error("", e); + return null; + } + } + // private static String getJavaVersion(Path path) { // // Find valid /bin folder // for (; path != null && !(Files.isDirectory(path.resolve("bin")) && Files.isReadable(path.resolve("bin"))); path = path.getParent()); diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/ModuleJandexIndex.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/ModuleJandexIndex.java new file mode 100644 index 000000000..4037ad32d --- /dev/null +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/ModuleJandexIndex.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2018 Pivotal, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.commons.jandex; + +import java.io.File; + +import org.jboss.jandex.IndexView; +import org.springframework.ide.vscode.commons.java.IJavaModuleData; + +import com.google.common.base.Supplier; + +class ModuleJandexIndex implements IJavaModuleData { + + private Supplier index; + + private File container; + + private String module; + + public ModuleJandexIndex(File container, String module, Supplier index) { + this.container = container; + this.module = module; + this.index = index; + } + + public Supplier getIndex() { + return index; + } + + @Override + public File getContainer() { + return container; + } + + @Override + public String getModule() { + return module; + } + + @Override + public String toString() { + return "ModuleJandexIndex [container=" + container + ", module=" + module + "]"; + } + +} diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/TypeImpl.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/TypeImpl.java index 9109099cc..4b6566be7 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/TypeImpl.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/TypeImpl.java @@ -11,7 +11,6 @@ package org.springframework.ide.vscode.commons.jandex; -import java.io.File; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -25,6 +24,7 @@ import org.jboss.jandex.Type; import org.springframework.ide.vscode.commons.java.Flags; import org.springframework.ide.vscode.commons.java.IAnnotation; import org.springframework.ide.vscode.commons.java.IField; +import org.springframework.ide.vscode.commons.java.IJavaModuleData; import org.springframework.ide.vscode.commons.java.IJavaType; import org.springframework.ide.vscode.commons.java.IJavadocProvider; import org.springframework.ide.vscode.commons.java.IMethod; @@ -36,9 +36,9 @@ class TypeImpl implements IType { private ClassInfo info; private JandexIndex index; private IJavadocProvider javadocProvider; - private File classpathContainer; + private IJavaModuleData classpathContainer; - TypeImpl(JandexIndex index, File classpathContainer, ClassInfo info, IJavadocProvider javadocProvider) { + TypeImpl(JandexIndex index, IJavaModuleData classpathContainer, ClassInfo info, IJavadocProvider javadocProvider) { this.info = info; this.index = index; this.classpathContainer = classpathContainer; @@ -154,7 +154,7 @@ class TypeImpl implements IType { } @Override - public File classpathContainer() { + public IJavaModuleData classpathContainer() { return classpathContainer; } diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/Wrappers.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/Wrappers.java index 3942e0469..1eb14304f 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/Wrappers.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/Wrappers.java @@ -13,8 +13,6 @@ package org.springframework.ide.vscode.commons.jandex; import static org.springframework.ide.vscode.commons.util.Assert.isNotNull; -import java.io.File; - import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationValue; import org.jboss.jandex.ClassInfo; @@ -26,6 +24,7 @@ import org.jboss.jandex.Type; import org.jboss.jandex.Type.Kind; import org.springframework.ide.vscode.commons.java.IAnnotation; import org.springframework.ide.vscode.commons.java.IField; +import org.springframework.ide.vscode.commons.java.IJavaModuleData; import org.springframework.ide.vscode.commons.java.IJavaType; import org.springframework.ide.vscode.commons.java.IJavadocProvider; import org.springframework.ide.vscode.commons.java.IMemberValuePair; @@ -36,11 +35,11 @@ import org.springframework.ide.vscode.commons.java.IVoidType; public class Wrappers { - public static IType wrap(JandexIndex index, File classpathContainer, ClassInfo info, IJavadocProvider javadocProvider) { + public static IType wrap(JandexIndex index, IJavaModuleData moduleContainer, ClassInfo info, IJavadocProvider javadocProvider) { if (info == null) { return null; } - return new TypeImpl(index, classpathContainer, info, javadocProvider); + return new TypeImpl(index, moduleContainer, info, javadocProvider); } public static IField wrap(IType declaringType, FieldInfo field, IJavadocProvider javadocProvider) { diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/BootProjectUtil.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/BootProjectUtil.java index be786dbf6..b88826c40 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/BootProjectUtil.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/BootProjectUtil.java @@ -11,8 +11,6 @@ package org.springframework.ide.vscode.commons.java; import java.io.File; -import java.nio.file.Files; -import java.nio.file.Path; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,38 +36,4 @@ public class BootProjectUtil { String name = cpe.getName(); return name.endsWith(".jar") && name.startsWith("spring-boot"); } - - public static Path javaHomeFromLibJar(Path libJar) { - Path root = libJar.getRoot(); - for (Path home = libJar; !root.equals(home.getParent()); home = home.getParent()) { - Path bin = home.resolve("bin"); - Path lib = home.resolve("lib"); - Path include = home.resolve("include"); - Path man = home.resolve("man"); - if (Files.isDirectory(bin) && Files.isDirectory(lib) && Files.isDirectory(include) && Files.isDirectory(man)) { - return home; - } - } - return null; - } - - public static Path jreSources(Path libJar) { - Path home = javaHomeFromLibJar(libJar); - if (home != null) { - Path sources = sourceZip(home); - if (sources == null) { - sources = sourceZip(home.resolve("lib")); - } - return sources; - } - return null; - } - - private static Path sourceZip(Path containerFolder) { - Path sourcesZip = containerFolder.resolve("src.zip"); - if (Files.exists(sourcesZip)) { - return sourcesZip; - } - return null; - } } diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/ClasspathIndex.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/ClasspathIndex.java index 6a098726c..8f818a7fb 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/ClasspathIndex.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/ClasspathIndex.java @@ -28,7 +28,7 @@ public interface ClasspathIndex extends Disposable { Flux> fuzzySearchPackages(String searchTerm); Flux allSubtypesOf(IType type); Flux allSuperTypesOf(IType type); - Optional findClasspathResourceContainer(String fqName); + IJavaModuleData findClasspathResourceContainer(String fqName); //Maybe the stuff below is another interface? Something that provides operations // on classpaths? diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IClasspathUtil.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IClasspathUtil.java index b3376223e..1506a751e 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IClasspathUtil.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IClasspathUtil.java @@ -68,7 +68,7 @@ public class IClasspathUtil { return Objects.equals(canonicalFile, classpathEntryFile); } - private static File binaryLocation(CPE cpe) { + public static File binaryLocation(CPE cpe) { switch (cpe.getKind()) { case Classpath.ENTRY_KIND_BINARY: return canonicalFile(cpe.getPath()); diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IField.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IField.java index a1abfa2af..110fc2081 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IField.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IField.java @@ -10,15 +10,13 @@ *******************************************************************************/ package org.springframework.ide.vscode.commons.java; -import java.io.File; - public interface IField extends IMember { boolean isEnumConstant(); IJavaType type(); @Override - default File classpathContainer() { + default IJavaModuleData classpathContainer() { return getDeclaringType().classpathContainer(); } diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IJavaModuleData.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IJavaModuleData.java new file mode 100644 index 000000000..996b5eafa --- /dev/null +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IJavaModuleData.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2018 Pivotal, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.commons.java; + +import java.io.File; + +public interface IJavaModuleData { + + File getContainer(); + + String getModule(); + +} diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IJavaProject.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IJavaProject.java index 205702ce5..6f266daf5 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IJavaProject.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IJavaProject.java @@ -57,7 +57,7 @@ public interface IJavaProject { return getIndex().getClasspathResources(); } - default Optional findClasspathResourceContainer(String fqName) { + default IJavaModuleData findClasspathResourceContainer(String fqName) { return getIndex().findClasspathResourceContainer(fqName); } diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IMember.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IMember.java index c8032b99a..093101ad3 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IMember.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IMember.java @@ -11,8 +11,6 @@ *******************************************************************************/ package org.springframework.ide.vscode.commons.java; -import java.io.File; - public interface IMember extends IJavaElement, IAnnotatable { /** @@ -45,7 +43,7 @@ public interface IMember extends IJavaElement, IAnnotatable { */ IType getDeclaringType(); - File classpathContainer(); + IJavaModuleData classpathContainer(); String signature(); diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IMethod.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IMethod.java index 6da1249ea..ff1bc73ab 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IMethod.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IMethod.java @@ -12,7 +12,6 @@ *******************************************************************************/ package org.springframework.ide.vscode.commons.java; -import java.io.File; import java.util.stream.Stream; public interface IMethod extends IMember { @@ -68,7 +67,7 @@ public interface IMethod extends IMember { boolean isConstructor(); @Override - default File classpathContainer() { + default IJavaModuleData classpathContainer() { return getDeclaringType().classpathContainer(); } diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaUtils.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/JavaUtils.java similarity index 68% rename from headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaUtils.java rename to headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/JavaUtils.java index 66e4ad1bc..b264c28c3 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaUtils.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/JavaUtils.java @@ -8,7 +8,7 @@ * Contributors: * Pivotal, Inc. - initial API and implementation *******************************************************************************/ -package org.springframework.ide.vscode.commons.languageserver.java; +package org.springframework.ide.vscode.commons.java; import java.io.File; import java.nio.file.Files; @@ -82,8 +82,45 @@ public class JavaUtils { return null; } } else { - return tokenized[0]; + String version = tokenized[0]; + int idx = version.indexOf('+'); + return idx >= 0 ? version.substring(0, idx) : version; } } + public static Path javaHomeFromLibJar(Path libJar) { + Path root = libJar.getRoot(); + for (Path home = libJar; !root.equals(home.getParent()); home = home.getParent()) { + Path bin = home.resolve("bin"); + Path lib = home.resolve("lib"); + Path include = home.resolve("include"); + Path man = home.resolve("man"); + Path legal = home.resolve("legal"); + if (Files.isDirectory(bin) && Files.isDirectory(lib) && Files.isDirectory(include) && (Files.isDirectory(man) || Files.isDirectory(legal))) { + return home; + } + } + return null; + } + + public static Path jreSources(Path libJar) { + Path home = javaHomeFromLibJar(libJar); + if (home != null) { + Path sources = JavaUtils.sourceZip(home); + if (sources == null) { + sources = JavaUtils.sourceZip(home.resolve("lib")); + } + return sources; + } + return null; + } + + private static Path sourceZip(Path containerFolder) { + Path sourcesZip = containerFolder.resolve("src.zip"); + if (Files.exists(sourcesZip)) { + return sourcesZip; + } + return null; + } + } diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/javadoc/JavaDocProviders.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/javadoc/JavaDocProviders.java index af2ed9d99..4787b3733 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/javadoc/JavaDocProviders.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/javadoc/JavaDocProviders.java @@ -13,7 +13,6 @@ package org.springframework.ide.vscode.commons.javadoc; import java.net.URL; import org.springframework.ide.vscode.commons.java.IJavadocProvider; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath; import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; public class JavaDocProviders { @@ -26,7 +25,7 @@ public class JavaDocProviders { ? TypeUrlProviderFromContainerUrl.JAR_JAVADOC_URL_PROVIDER : TypeUrlProviderFromContainerUrl.JAVADOC_FOLDER_URL_SUPPLIER; return new HtmlJavadocProvider( - type -> urlProvider.url(classpathEntry.getJavadocContainerUrl(), type.getFullyQualifiedName()) + type -> urlProvider.url(classpathEntry.getJavadocContainerUrl(), type.getFullyQualifiedName(), type.classpathContainer().getModule()) ); } return null; diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/javadoc/TypeUrlProviderFromContainerUrl.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/javadoc/TypeUrlProviderFromContainerUrl.java index f50c6a822..3749e647b 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/javadoc/TypeUrlProviderFromContainerUrl.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/javadoc/TypeUrlProviderFromContainerUrl.java @@ -16,29 +16,34 @@ import java.nio.file.Paths; @FunctionalInterface public interface TypeUrlProviderFromContainerUrl { - + static String extractTopLevelType(String fqName) { int innerTypeIdx = fqName.indexOf('$'); return innerTypeIdx > 0 ? fqName.substring(0, innerTypeIdx) : fqName; } - - public static final TypeUrlProviderFromContainerUrl JAR_SOURCE_URL_PROVIDER = (jarSourceUrl, fqName) -> { + + public static final TypeUrlProviderFromContainerUrl JAR_SOURCE_URL_PROVIDER = (jarSourceUrl, fqName, module) -> { StringBuilder urlStr = new StringBuilder(); urlStr.append("jar:"); urlStr.append(jarSourceUrl); urlStr.append("!"); urlStr.append('/'); + if (module != null) { + urlStr.append(module); + urlStr.append('/'); + } urlStr.append(extractTopLevelType(fqName).replaceAll("\\.", "/")); urlStr.append(".java"); return new URL(urlStr.toString()); }; - - public static final TypeUrlProviderFromContainerUrl SOURCE_FOLDER_URL_SUPPLIER = (sourceContainerUrl, fqName) -> { + + public static final TypeUrlProviderFromContainerUrl SOURCE_FOLDER_URL_SUPPLIER = (sourceContainerUrl, fqName, module) -> { + // Unclear how to deal with modules and source folders at the moment hence module is ignored return Paths.get(sourceContainerUrl.toURI()).resolve(extractTopLevelType(fqName).replaceAll("\\.", "/") + ".java").toUri().toURL(); }; - - public static final TypeUrlProviderFromContainerUrl JAR_JAVADOC_URL_PROVIDER = (javadocContainerUrl, fqName) -> { + + public static final TypeUrlProviderFromContainerUrl JAR_JAVADOC_URL_PROVIDER = (javadocContainerUrl, fqName, module) -> { StringBuilder urlStr = new StringBuilder(); urlStr.append("jar:"); urlStr.append(javadocContainerUrl); @@ -50,8 +55,8 @@ public interface TypeUrlProviderFromContainerUrl { return new URL(urlStr.toString()); }; - - public static final TypeUrlProviderFromContainerUrl JAVADOC_FOLDER_URL_SUPPLIER = (javadocContainerUrl, fqName) -> { + + public static final TypeUrlProviderFromContainerUrl JAVADOC_FOLDER_URL_SUPPLIER = (javadocContainerUrl, fqName, module) -> { String urlStr = javadocContainerUrl.toString(); StringBuilder sb = new StringBuilder(urlStr); if (!urlStr.endsWith("/")) { @@ -61,7 +66,7 @@ public interface TypeUrlProviderFromContainerUrl { sb.append(fqName.replaceAll("\\.", "/").replaceAll("\\$", ".") + ".html"); return new URL(sb.toString()); }; - - URL url(URL containerUrl, String fqName) throws Exception; + + URL url(URL containerUrl, String fqName, String module) throws Exception; } diff --git a/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenCore.java b/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenCore.java index fa68242f3..01093dc71 100644 --- a/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenCore.java +++ b/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenCore.java @@ -54,7 +54,7 @@ import org.eclipse.aether.util.graph.visitor.CloningDependencyVisitor; import org.eclipse.aether.util.graph.visitor.FilteringDependencyVisitor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.ide.vscode.commons.languageserver.java.JavaUtils; +import org.springframework.ide.vscode.commons.java.JavaUtils; /** * Maven Core functionality diff --git a/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenProjectClasspath.java b/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenProjectClasspath.java index ee81afbfb..97380be28 100644 --- a/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenProjectClasspath.java +++ b/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenProjectClasspath.java @@ -22,9 +22,9 @@ import java.util.Set; import org.apache.maven.artifact.Artifact; import org.apache.maven.model.Resource; import org.apache.maven.project.MavenProject; -import org.springframework.ide.vscode.commons.java.BootProjectUtil; import org.springframework.ide.vscode.commons.java.ClasspathData; import org.springframework.ide.vscode.commons.java.IClasspath; +import org.springframework.ide.vscode.commons.java.JavaUtils; import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; import org.springframework.ide.vscode.commons.maven.MavenCore; import org.springframework.ide.vscode.commons.maven.MavenException; @@ -92,7 +92,7 @@ public class MavenProjectClasspath implements IClasspath { cpe.setSystem(true); entries.add(cpe); // Add at the end, not critical if throws exception, but the CPE needs to be around regardless if the below throws - Path sources = BootProjectUtil.jreSources(path); + Path sources = JavaUtils.jreSources(path); if (sources != null) { cpe.setSourceContainerUrl(sources.toUri().toURL()); } diff --git a/headless-services/commons/commons-maven/src/test/java/org/springframework/ide/vscode/commons/maven/HtmlJavadocTest.java b/headless-services/commons/commons-maven/src/test/java/org/springframework/ide/vscode/commons/maven/HtmlJavadocTest.java index d5f57df21..65186e5d4 100644 --- a/headless-services/commons/commons-maven/src/test/java/org/springframework/ide/vscode/commons/maven/HtmlJavadocTest.java +++ b/headless-services/commons/commons-maven/src/test/java/org/springframework/ide/vscode/commons/maven/HtmlJavadocTest.java @@ -20,6 +20,7 @@ import java.nio.file.Paths; import java.util.stream.Stream; import org.junit.Assume; +import org.junit.Ignore; import org.junit.Test; import org.springframework.ide.vscode.commons.java.IField; import org.springframework.ide.vscode.commons.java.IMethod; @@ -33,6 +34,8 @@ import org.springframework.ide.vscode.commons.util.FileObserver; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; +@Ignore +//@EnabledOnJre(JAVA_8) public class HtmlJavadocTest { private static FileObserver fileObserver = new BasicFileObserver(); diff --git a/headless-services/commons/commons-maven/src/test/java/org/springframework/ide/vscode/commons/maven/JavaIndexTest.java b/headless-services/commons/commons-maven/src/test/java/org/springframework/ide/vscode/commons/maven/JavaIndexTest.java index c17b2207f..4e2b03d12 100644 --- a/headless-services/commons/commons-maven/src/test/java/org/springframework/ide/vscode/commons/maven/JavaIndexTest.java +++ b/headless-services/commons/commons-maven/src/test/java/org/springframework/ide/vscode/commons/maven/JavaIndexTest.java @@ -17,20 +17,19 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.springframework.ide.vscode.languageserver.testharness.ClasspathTestUtil.getOutputFolder; -import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; -import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; import org.junit.Test; import org.springframework.ide.vscode.commons.java.Flags; +import org.springframework.ide.vscode.commons.java.IJavaModuleData; import org.springframework.ide.vscode.commons.java.IMethod; import org.springframework.ide.vscode.commons.java.IPrimitiveType; import org.springframework.ide.vscode.commons.java.IType; @@ -103,6 +102,15 @@ public class JavaIndexTest { assertNotNull(type); } +// @Test +// public void findStringStripMethodinJDK() throws Exception { +// MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file"); +// IType type = project.findType("java.lang.String"); +// assertNotNull(type); +// IMethod method = type.getMethod("strip", Stream.empty()); +// assertNotNull(method); +// } + @Test public void findClassInOutputFolder() throws Exception { MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file"); @@ -154,18 +162,18 @@ public class JavaIndexTest { @Test public void testFindJarResource() throws Exception { MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file"); - Optional jar = project.findClasspathResourceContainer("org.springframework.boot.autoconfigure.SpringBootApplication"); - assertTrue(jar.isPresent()); - assertEquals("spring-boot-autoconfigure-1.4.1.RELEASE.jar", jar.get().getName()); + IJavaModuleData module = project.findClasspathResourceContainer("org.springframework.boot.autoconfigure.SpringBootApplication"); + assertNotNull(module); + assertEquals("spring-boot-autoconfigure-1.4.1.RELEASE.jar", module.getContainer().getName()); } @Test public void testFindJavaResource() throws Exception { MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file"); - Optional file = project.findClasspathResourceContainer("hello.GreetingController"); - assertTrue(file.isPresent()); - assertTrue(file.get().exists()); - assertEquals(getOutputFolder(project).toString(), file.get().toString()); + IJavaModuleData module = project.findClasspathResourceContainer("hello.GreetingController"); + assertNotNull(module); + assertTrue(module.getContainer().exists()); + assertEquals(getOutputFolder(project).toString(), module.getContainer().toString()); } @Test diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/AbstractSourceLinks.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/AbstractSourceLinks.java index fe3688544..035a91c77 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/AbstractSourceLinks.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/AbstractSourceLinks.java @@ -28,6 +28,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ide.vscode.boot.java.utils.CompilationUnitCache; import org.springframework.ide.vscode.commons.java.IClasspath; +import org.springframework.ide.vscode.commons.java.IJavaModuleData; import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.javadoc.TypeUrlProviderFromContainerUrl; import org.springframework.ide.vscode.commons.util.text.Region; @@ -50,13 +51,13 @@ public abstract class AbstractSourceLinks implements SourceLinks { @Override public Optional sourceLinkUrlForFQName(IJavaProject project, String fqName) { - Optional classpathResource = project.getIndex().findClasspathResourceContainer(fqName); - if (classpathResource.isPresent()) { - File file = classpathResource.get(); + IJavaModuleData classpathResource = project.getIndex().findClasspathResourceContainer(fqName); + if (classpathResource != null) { + File file = classpathResource.getContainer(); if (file.isDirectory()) { - return javaSourceLinkUrl(project, fqName, file); + return javaSourceLinkUrl(project, fqName, classpathResource); } else { - return jarSourceLinkUrl(project, fqName, file); + return jarSourceLinkUrl(project, fqName, classpathResource); } } return Optional.empty(); @@ -74,7 +75,7 @@ public abstract class AbstractSourceLinks implements SourceLinks { - private Optional javaSourceLinkUrl(IJavaProject project, String fqName, File containerFolder) { + private Optional javaSourceLinkUrl(IJavaProject project, String fqName, IJavaModuleData folderModuleData) { IClasspath classpath = project.getClasspath(); return SourceLinks.sourceFromSourceFolder(fqName, classpath) .map(sourcePath -> javaSourceLinkUrl(project, sourcePath, fqName)); @@ -95,19 +96,19 @@ public abstract class AbstractSourceLinks implements SourceLinks { return cuCache == null ? Optional.empty() : cuCache.withCompilationUnit(project, uri, compilationUnit -> Optional.ofNullable(compilationUnit)); } - abstract protected Optional jarLinkUrl(IJavaProject project, String fqName, File jarFile); + abstract protected Optional jarLinkUrl(IJavaProject project, String fqName, IJavaModuleData jarModuleData); - private Optional jarSourceLinkUrl(IJavaProject project, String fqName, File jarFile) { - return jarLinkUrl(project, fqName, jarFile).map(sourceUrl -> { - Optional positionLink = findCUForFQNameFromJar(project, jarFile, fqName).map(cu -> positionLink(cu, fqName)); + private Optional jarSourceLinkUrl(IJavaProject project, String fqName, IJavaModuleData jarModuleData) { + return jarLinkUrl(project, fqName, jarModuleData).map(sourceUrl -> { + Optional positionLink = findCUForFQNameFromJar(project, jarModuleData, fqName).map(cu -> positionLink(cu, fqName)); return positionLink.isPresent() ? sourceUrl + positionLink.get() : sourceUrl; }); } - private Optional findCUForFQNameFromJar(IJavaProject project, File jarFile, String fqName) { - return project.sourceContainer(jarFile).map(url -> { + private Optional findCUForFQNameFromJar(IJavaProject project, IJavaModuleData jarModuleData, String fqName) { + return project.sourceContainer(jarModuleData.getContainer()).map(url -> { try { - return TypeUrlProviderFromContainerUrl.JAR_SOURCE_URL_PROVIDER.url(url, fqName); + return TypeUrlProviderFromContainerUrl.JAR_SOURCE_URL_PROVIDER.url(url, fqName, jarModuleData.getModule()); } catch (Exception e) { log.warn("Failed to determine source URL from url={} fqName={}", url, fqName, e); return null; diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/AtomSourceLinks.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/AtomSourceLinks.java index a4d4d6476..29e58bf83 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/AtomSourceLinks.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/AtomSourceLinks.java @@ -10,7 +10,6 @@ *******************************************************************************/ package org.springframework.ide.vscode.boot.java.links; -import java.io.File; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.file.Path; @@ -20,6 +19,7 @@ import org.eclipse.jdt.core.dom.CompilationUnit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ide.vscode.boot.java.utils.CompilationUnitCache; +import org.springframework.ide.vscode.commons.java.IJavaModuleData; import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.util.text.Region; @@ -69,7 +69,7 @@ public class AtomSourceLinks extends AbstractSourceLinks { } @Override - protected Optional jarLinkUrl(IJavaProject project, String fqName, File jarFile) { + protected Optional jarLinkUrl(IJavaProject project, String fqName, IJavaModuleData jarModuleData) { // JAR URLs are not supported yet return Optional.empty(); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/JdtJavaDocumentUriProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/JdtJavaDocumentUriProvider.java index e6301d05a..06b2967bd 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/JdtJavaDocumentUriProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/JdtJavaDocumentUriProvider.java @@ -13,11 +13,11 @@ package org.springframework.ide.vscode.boot.java.links; import java.io.File; import java.net.URI; import java.net.URLEncoder; -import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ide.vscode.commons.java.IClasspath; +import org.springframework.ide.vscode.commons.java.IJavaModuleData; import org.springframework.ide.vscode.commons.java.IJavaProject; public class JdtJavaDocumentUriProvider implements JavaDocumentUriProvider { @@ -30,9 +30,9 @@ public class JdtJavaDocumentUriProvider implements JavaDocumentUriProvider { } public static URI uri(IJavaProject project, String fqName) { - Optional classpathResource = project.getIndex().findClasspathResourceContainer(fqName); - if (classpathResource.isPresent()) { - File file = classpathResource.get(); + IJavaModuleData classpathResource = project.getIndex().findClasspathResourceContainer(fqName); + if (classpathResource != null) { + File file = classpathResource.getContainer(); if (file.isDirectory()) { IClasspath classpath = project.getClasspath(); return SourceLinks.sourceFromSourceFolder(fqName, classpath).map(path -> path.toUri()).orElse(null); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/SourceLinks.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/SourceLinks.java index 97db096ed..af347170b 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/SourceLinks.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/SourceLinks.java @@ -10,7 +10,6 @@ *******************************************************************************/ package org.springframework.ide.vscode.boot.java.links; -import java.io.File; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; @@ -23,6 +22,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ide.vscode.commons.java.IClasspath; import org.springframework.ide.vscode.commons.java.IClasspathUtil; +import org.springframework.ide.vscode.commons.java.IJavaModuleData; import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.javadoc.TypeUrlProviderFromContainerUrl; @@ -54,7 +54,7 @@ public interface SourceLinks { }) .map(url -> { try { - return TypeUrlProviderFromContainerUrl.SOURCE_FOLDER_URL_SUPPLIER.url(url, fqName); + return TypeUrlProviderFromContainerUrl.SOURCE_FOLDER_URL_SUPPLIER.url(url, fqName, /* module */ null); } catch (Exception e) { log.warn("Failed to determine source URL from url={} fqName=", url, fqName, e); return null; @@ -73,31 +73,30 @@ public interface SourceLinks { } public static Optional source(IJavaProject project, String fqName) { - Optional classpathResourceContainer = project.findClasspathResourceContainer(fqName); // Try to find in a source JAR - Optional url = classpathResourceContainer - .flatMap(file -> project.sourceContainer(file)) - .map(file -> { + IJavaModuleData classpathResourceContainer = project.findClasspathResourceContainer(fqName); + if (classpathResourceContainer != null) { + Optional url = project.sourceContainer(classpathResourceContainer.getContainer()).map(file -> { + try { + return TypeUrlProviderFromContainerUrl.JAR_SOURCE_URL_PROVIDER.url(file, fqName, classpathResourceContainer.getModule()); + } catch (Exception e) { + throw new IllegalStateException(e); + } + }); + + if (!url.isPresent()) { + // Try Source folder + url = sourceFromSourceFolder(fqName, project.getClasspath()).map(p -> { try { - return TypeUrlProviderFromContainerUrl.JAR_SOURCE_URL_PROVIDER.url(file, fqName); - } catch (Exception e) { + return p.toUri().toURL(); + } catch (MalformedURLException e) { throw new IllegalStateException(e); } }); - - - if (!url.isPresent()) { - // Try Source folder - url = classpathResourceContainer - .flatMap(file -> sourceFromSourceFolder(fqName, project.getClasspath()).map(p -> { - try { - return p.toUri().toURL(); - } catch (MalformedURLException e) { - throw new IllegalStateException(e); - } - })); + } + return url; } - return url; + return Optional.empty(); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/VSCodeSourceLinks.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/VSCodeSourceLinks.java index 54eab45f3..c34b2551c 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/VSCodeSourceLinks.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/VSCodeSourceLinks.java @@ -10,12 +10,12 @@ *******************************************************************************/ package org.springframework.ide.vscode.boot.java.links; -import java.io.File; import java.nio.file.Path; import java.util.Optional; import org.eclipse.jdt.core.dom.CompilationUnit; import org.springframework.ide.vscode.boot.java.utils.CompilationUnitCache; +import org.springframework.ide.vscode.commons.java.IJavaModuleData; import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.util.text.Region; @@ -55,7 +55,7 @@ public class VSCodeSourceLinks extends AbstractSourceLinks { } @Override - protected Optional jarLinkUrl(IJavaProject project, String fqName, File jarFile) { + protected Optional jarLinkUrl(IJavaProject project, String fqName, IJavaModuleData jarModuleData) { return Optional.ofNullable(JdtJavaDocumentUriProvider.uri(project, fqName)).map(uri -> uri.toString()); } diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/metadata/LoggerNameProviderTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/metadata/LoggerNameProviderTest.java index 1d1219708..7ed16be0a 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/metadata/LoggerNameProviderTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/metadata/LoggerNameProviderTest.java @@ -39,19 +39,18 @@ import com.google.common.collect.ImmutableSet; public class LoggerNameProviderTest { private static final String[] JBOSS_RESULTS = { - "com.fasterxml.jackson.databind.jsonFormatVisitors", //1 // org.jboss is not really a package... -// "org.jboss", //2 - "org.jboss.logging", //3 - "org.jboss.logging.JBossLogManagerLogger", //4 - "org.jboss.logging.JBossLogManagerProvider", //5 - "org.jboss.logging.JBossLogRecord", //6 - "org.springframework.instrument.classloading.jboss", //7 - "org.springframework.instrument.classloading.jboss.JBossClassLoaderAdapter", //8 - "org.springframework.instrument.classloading.jboss.JBossLoadTimeWeaver", //9 - "org.springframework.instrument.classloading.jboss.JBossMCAdapter", //10 - "org.springframework.instrument.classloading.jboss.JBossMCTranslatorAdapter", //11 - "org.springframework.instrument.classloading.jboss.JBossModulesAdapter" //12 +// "org.jboss", //1 + "org.jboss.logging", //2 + "org.jboss.logging.JBossLogManagerLogger", //3 + "org.jboss.logging.JBossLogManagerProvider", //4 + "org.jboss.logging.JBossLogRecord", //5 + "org.springframework.instrument.classloading.jboss", //6 + "org.springframework.instrument.classloading.jboss.JBossClassLoaderAdapter", //7 + "org.springframework.instrument.classloading.jboss.JBossLoadTimeWeaver", //8 + "org.springframework.instrument.classloading.jboss.JBossMCAdapter", //9 + "org.springframework.instrument.classloading.jboss.JBossMCTranslatorAdapter", //10 + "org.springframework.instrument.classloading.jboss.JBossModulesAdapter" //11 }; private ProjectsHarness projects = ProjectsHarness.INSTANCE;