Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,6 @@ protected void doClose() {

@Override
protected ScannerService getScannerService() {
return new OWBTomcatWebScannerService(scannerService, scannerService::getFinder);
return new OWBTomcatWebScannerService(scannerService);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,41 +22,34 @@
import org.apache.meecrowave.logging.tomcat.LogFacade;
import org.apache.tomcat.JarScanFilter;
import org.apache.webbeans.config.WebBeansContext;
import org.apache.webbeans.corespi.scanner.xbean.CdiArchive;
import org.apache.webbeans.corespi.scanner.AbstractMetaDataDiscovery;
import org.apache.webbeans.corespi.scanner.xbean.OwbAnnotationFinder;
import org.apache.webbeans.spi.BDABeansXmlScanner;
import org.apache.webbeans.spi.BdaScannerService;
import org.apache.webbeans.spi.BeanArchiveService;
import org.apache.webbeans.util.WebBeansUtil;
import org.apache.webbeans.web.scanner.WebScannerService;
import org.apache.xbean.finder.AnnotationFinder;
import org.apache.xbean.finder.filter.Filter;

import jakarta.servlet.ServletContext;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.Collection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Stream;

import static java.util.Optional.of;
import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.toSet;
import static org.apache.tomcat.JarScanType.PLUGGABILITY;

public class OWBTomcatWebScannerService extends WebScannerService {
private final LogFacade logger = new LogFacade(OWBTomcatWebScannerService.class.getName());
private final BdaScannerService delegate;
private final Supplier<OwbAnnotationFinder> finderAccessor;

protected JarScanFilter filter;
private String jreBase;
Expand All @@ -67,14 +60,17 @@ public class OWBTomcatWebScannerService extends WebScannerService {
private String shared;
private Consumer<File> fileVisitor;

/**
* Contains manually added classes, e.g. from Groovy scanning.
*/
private List<Class<?>> additionalClasses = null;

public OWBTomcatWebScannerService() {
this(null, null);
this(null);
}


public OWBTomcatWebScannerService(final BdaScannerService delegate, final Supplier<OwbAnnotationFinder> finderAccessor) {
public OWBTomcatWebScannerService(final BdaScannerService delegate) {
this.delegate = delegate;
this.finderAccessor = finderAccessor;
}

@Override
Expand Down Expand Up @@ -108,14 +104,6 @@ public BDABeansXmlScanner getBDABeansXmlScanner() {
return delegate.getBDABeansXmlScanner();
}

@Override
public OwbAnnotationFinder getFinder() {
if (finderAccessor != null) {
return finderAccessor.get();
}
return super.getFinder();
}

@Override
public Map<BeanArchiveService.BeanArchiveInformation, Set<Class<?>>> getBeanClassesPerBda() {
if (delegate != null) {
Expand All @@ -135,25 +123,33 @@ public void release() {

@Override
public Set<Class<?>> getBeanClasses() {
Set<Class<?>> beanClasses;
if (delegate != null) {
return delegate.getBeanClasses();
beanClasses = delegate.getBeanClasses();
}
return super.getBeanClasses();
else {
beanClasses = super.getBeanClasses();
}

if (additionalClasses != null) {
beanClasses.addAll(additionalClasses);
}

return beanClasses;
}

@Override
public List<OwbAnnotationFinder> getAnnotationFinders() {
if (delegate != null && delegate instanceof AbstractMetaDataDiscovery) {
return ((AbstractMetaDataDiscovery) delegate).getAnnotationFinders();
}
return super.getAnnotationFinders();
}

@Override
public void scan() {
if (delegate != null) {
if (getFinder() == null) {
delegate.scan();
}
if (finder == null) {
finder = getFinder();
}
}

if (finder != null) {
return;
}

super.scan();
Expand Down Expand Up @@ -239,46 +235,7 @@ private void addClassesToDefault(final Class<?>[] all) throws Exception {
return;
}

final Field linking = AnnotationFinder.class.getDeclaredField("linking");
final Method readClassDef = AnnotationFinder.class.getDeclaredMethod("readClassDef", Class.class);
if (!readClassDef.isAccessible()) {
readClassDef.setAccessible(true);
}
if (!linking.isAccessible()) {
linking.setAccessible(true);
}

final URI uri = URI.create("jar:file://!/"); // we'll never find it during scanning and it avoids to create a custom handler
final URL url = uri.toURL();
final String key = uri.toASCIIString();
CdiArchive.FoundClasses foundClasses = archive.classesByUrl().get(key);
if (foundClasses == null) {
final BeanArchiveService beanArchiveService = webBeansContext().getBeanArchiveService();
foundClasses = new CdiArchive.FoundClasses(url, new HashSet<>(), beanArchiveService.getBeanArchiveInformation(url));
archive.classesByUrl().put(key, foundClasses);
}

foundClasses.getClassNames().addAll(Stream.of(all).map(Class::getName).collect(toSet()));

try {
linking.set(finder, true);

Stream.of(all).forEach(c -> { // populate classInfos map to support annotated mode which relies on ClassInfo
try {
readClassDef.invoke(finder, c);
} catch (final IllegalAccessException e) {
throw new IllegalStateException(e);
} catch (final InvocationTargetException e) {
throw new IllegalStateException(e.getCause());
}
});
} finally {
try {
linking.set(finder, false);
} catch (final IllegalAccessException e) {
// no-op
}
}
additionalClasses = new ArrayList<>(Arrays.asList(all));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
Expand Down Expand Up @@ -65,7 +66,7 @@ public class MeecrowaveContextConfig extends ContextConfig {
private final boolean fixDocBase;
private final ServletContainerInitializer intializer;
private final Consumer<Context> redeployCallback;
private OwbAnnotationFinder finder;
private List<OwbAnnotationFinder> annotationFinders;
private ReloadOnChangeController watcher;

public MeecrowaveContextConfig(final Configuration configuration, final boolean fixDocBase, final ServletContainerInitializer intializer, final Consumer<Context> redeployCallback) {
Expand Down Expand Up @@ -113,24 +114,27 @@ protected void webConfig() {
scannerService.setFileVisitor(f -> watcher.register(f));
}
scannerService.scan();
finder = scannerService.getFinder();
finder.link();
final CdiArchive archive = CdiArchive.class.cast(finder.getArchive());
Stream.of(WebServlet.class, WebFilter.class, WebListener.class)
.forEach(marker -> finder.findAnnotatedClasses(marker).stream()
.filter(c -> !Modifier.isAbstract(c.getModifiers()) && Modifier.isPublic(c.getModifiers()))
.forEach(webComponent -> webClasses.computeIfAbsent(
archive.classesByUrl().entrySet().stream()
.filter(e -> e.getValue().getClassNames().contains(webComponent.getName()))
.findFirst().get().getKey(), k -> new HashSet<>())
.add(webComponent)));
annotationFinders = scannerService.getAnnotationFinders();

for (OwbAnnotationFinder finder : annotationFinders) {
finder.link();
final CdiArchive archive = CdiArchive.class.cast(finder.getArchive());
Stream.of(WebServlet.class, WebFilter.class, WebListener.class)
.forEach(marker -> finder.findAnnotatedClasses(marker).stream()
.filter(c -> !Modifier.isAbstract(c.getModifiers()) && Modifier.isPublic(c.getModifiers()))
.forEach(webComponent -> webClasses.computeIfAbsent(
archive.classesByUrl().entrySet().stream()
.filter(e -> e.getValue().getClassNames().contains(webComponent.getName()))
.findFirst().get().getKey(), k -> new HashSet<>())
.add(webComponent)));
}
}

super.webConfig();
} finally {
thread.setContextClassLoader(old);
webClasses.clear();
finder = null;
annotationFinders = null;
}
}

Expand Down Expand Up @@ -197,16 +201,18 @@ protected void processServletContainerInitializers() { // use our finder
if (ht == null) {
return;
}
Stream.of(ht.value()).forEach(t -> {
if (t.isAnnotation()) {
final Class<? extends Annotation> annotation = Class.class.cast(t);
classes.addAll(finder.findAnnotatedClasses(annotation));
} else if (t.isInterface()) {
classes.addAll(finder.findImplementations(t));
} else {
classes.addAll(finder.findSubclasses(t));
}
});
for (OwbAnnotationFinder finder : annotationFinders) {
Stream.of(ht.value()).forEach(t -> {
if (t.isAnnotation()) {
final Class<? extends Annotation> annotation = Class.class.cast(t);
classes.addAll(finder.findAnnotatedClasses(annotation));
} else if (t.isInterface()) {
classes.addAll(finder.findImplementations(t));
} else {
classes.addAll(finder.findSubclasses(t));
}
});
}
});
} catch (final IOException e) {
ok = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;

public class OWBJarScanner implements JarScanner {
private JarScanFilter filter; // not yet used
Expand All @@ -50,37 +51,39 @@ public void scan(final JarScanType jarScanType, final ServletContext servletCont
if (!WebScannerService.class.isInstance(scannerService)) {
return;
}
final OwbAnnotationFinder finder = WebScannerService.class.cast(scannerService).getFinder();
if (finder == null) {
final List<OwbAnnotationFinder> annotationFinders = WebScannerService.class.cast(scannerService).getAnnotationFinders();
if (annotationFinders == null || annotationFinders.isEmpty()) {
return;
}
CdiArchive.class.cast(finder.getArchive())
.classesByUrl().keySet().stream()
.filter(u -> !"jar:file://!/".equals(u)) // not a fake in memory url
.forEach(u -> {
try {
final URL url = new URL(u);
final File asFile = Files.toFile(url);
if (!asFile.exists()) {
return;
}
if (filter != null && !filter.check(jarScanType, asFile.getName())) {
return;
}
for (OwbAnnotationFinder finder : annotationFinders) {
CdiArchive.class.cast(finder.getArchive())
.classesByUrl().keySet().stream()
.filter(u -> !"jar:file://!/".equals(u)) // not a fake in memory url
.forEach(u -> {
try {
final URL url = new URL(u);
final File asFile = Files.toFile(url);
if (!asFile.exists()) {
return;
}
if (filter != null && !filter.check(jarScanType, asFile.getName())) {
return;
}

if (asFile.getName().endsWith(Constants.JAR_EXT)) {
try (final Jar jar = JarFactory.newInstance(asFile.toURI().toURL())) {
callback.scan(jar, u, true);
if (asFile.getName().endsWith(Constants.JAR_EXT)) {
try (final Jar jar = JarFactory.newInstance(asFile.toURI().toURL())) {
callback.scan(jar, u, true);
}
} else if (asFile.isDirectory()) {
callback.scan(asFile, asFile.getAbsolutePath(), true);
}
} else if (asFile.isDirectory()) {
callback.scan(asFile, asFile.getAbsolutePath(), true);
} catch (final MalformedURLException e) {
// skip
} catch (final IOException ioe) {
throw new IllegalArgumentException(ioe);
}
} catch (final MalformedURLException e) {
// skip
} catch (final IOException ioe) {
throw new IllegalArgumentException(ioe);
}
});
});
}
return;

case TLD:
Expand Down
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,17 +76,17 @@

<tomcat.version>11.0.22</tomcat.version>

<openwebbeans.version>4.1.0</openwebbeans.version>
<openwebbeans.version>4.1.1-SNAPSHOT</openwebbeans.version>
<cxf.version>4.1.5</cxf.version>
<johnzon.version>2.1.0</johnzon.version>
<johnzon.version>2.1.1-SNAPSHOT</johnzon.version>
<log4j2.version>2.25.4</log4j2.version>
<deltaspike.version>2.0.1</deltaspike.version>
<jaxb.version>2.3.0</jaxb.version>
<openjpa.version>4.1.1</openjpa.version>
<h2.version>2.4.240</h2.version>
<dbcp2.version>2.13.0</dbcp2.version>
<commons-cli.version>1.11.0</commons-cli.version>
<xbean.version>4.30</xbean.version>
<xbean.version>5.0.0-SNAPSHOT</xbean.version>
<geronimo-jcache-simple.version>1.0.5</geronimo-jcache-simple.version>
<geronimo-jcache_1.0_spec.version>1.0-alpha-1</geronimo-jcache_1.0_spec.version>

Expand Down
Loading