Classpath scan¶
Summary
Use scan only for application package. When part of application extracted to its own library (usually already mature part) create guicey bundle for it with explicit extensions definition. Use manual bundles installation or bundle lookup mechanism to install custom bundles.
Configuration¶
Classpath scanning is activated by specifying package to scan in bundle:
GuiceBundle.builder()
.enableAutoConfig("package.to.scan")
Or multiple packages:
GuiceBundle.builder()
.enableAutoConfig("com.mycompany.pkg1", "com.mycompany.pkg2")
If no packages specified, classpath scan would be activated for application package:
GuiceBundle.builder()
.enableAutoConfig()
(equivalent to .enableAutoConfig(getClass().getPackage().getName())
How it works¶
When auto scan enabled:
- Extension installers are searched in classpath (classes implementing
FeatureInstaller
). - Extensions are searched using registered installers (
FeatureInstaller#matches
method). - If commands search is enabled (
.searchCommands()
), performs search for all classes extendingCommand
and install them into bootstrap.
Classes are searched in specified packages and all their subpackages. Abstract classes are ignored.
Inner static classes are also resolved:
public abstract class AbstractExceptionMapper<T extends Exception> implements ExceptionMapper<T> {
@Provider
public static class FooExceptionMapper extends AbstractExceptionMapper<IOException> { ... }
@Provider
public static class BarExceptionMapper extends AbstractExceptionMapper<ServletException> { ... }
}
FooExceptionMapper
and BarExceptionMapper
would be detected and installed.
Hide class from scan¶
@InvisibleForScanner
annotation hides class from scanner (for example, to install it manually or to avoid installation at all)
@Provider
@InvisibleForScanner
public static class FooExceptionMapper extends AbstractExceptionMapper<IOException> { ... }
In this case FooExceptionMapper
will be ignored by classpath scanner. But you still can install extension manually.
Tip
If you can't use annotation on extension for some reason, you can simply disable extension
Motivation¶
Usually, dropwizard applications are not so big (middle to small) and all classes in application package are used (so you will load all of them in any case).
Classpath scan looks for all classes in provided package(s) and loads all found classes. Usual solutions like reflections, fast scanner or even jersey's internal classpath scan parse class structure instead of loading classes. In general cases, it is better solution, but, as we use all application classes in any case, loading all of them a bit earlier is not a big deal. Moreover, operations with loaded classes are much simpler then working with class structure (and so installers matching logic becomes very simple).
Using classpath scan is very handy during development: you simply add features (resources, tasks, servlets etc) and they are automatically discovered and installer. Actual application configuration could always be checked with diagnostic output), so there should not be any problems for using classpath scan for production too.
Warning
It's a bad idea to use classpath scan for resolving extensions from 3rd party jars. Group extensions from external jars into bundles. Usually, external libraries are well defined and all used extensions are already known and unlikely to change often, so it's better to manually install them through custom guicey bundle: bundle "documents" extensions. If you want plug-n-play behaviour (bundle installed when jar appear in classpath) then use bundle lookup (enabled by default) which could load bundles with service loader definition.