Dropwizard Guicey

repository·master·Indexed 42 days ago

https://github.com/xvik/dropwizard-guicey

A library providing seamless integration between the Dropwizard framework and Google Guice, enabling dependency injection and advanced configuration management. It features automatic bundle loading via ServiceLoader, classpath scanning for extensions, custom installers, and support for Guice-managed and HK2-managed sub-resources via the HK Bridge.

Tokens
122.2K
Snippets
385
Records
480
Agent score
54%

What's inside Dropwizard Guicey

  1. Overview of dropwizard-guicey

    master

    dropwizard-guicey provides Google Guice integration for Dropwizard applications. It is compiled for java 11 and is compatible with java 11 through java 21.

    Main Features

    • Auto configuration: Uses classpath scanning and Guice bindings.
    • Yaml config bindings: Bind configuration values from YAML files by path or unique sub-objects.
    • Web support: Advanced integration for web-related components.
    • Console reporting: Automatically detects and prints installed extensions to the console.
    • Test support: Custom JUnit and Spock extensions with abilities to disable or override application logic.
    • Extensibility: Rich API for custom integrations, lifecycle hooks, and plug-and-play plugins via ServiceLoader lookup.
  2. Explore dropwizard-guicey examples

    master
    The examples directory contains various implementations of dropwizard-guicey features, ranging from core Guice integration to specific extension modules and third-party integrations. Use these examples to understand how to implement specific patterns in your Dropwizard application.
  3. Configure Row Mappers and Custom Binding

    master

    The guicey-jdbi3 extension includes a Row Mapper installer that automatically detects all implementations of RowMapper and registers them in the JDBI instance.

    Row mappers are instantiated as standard Guice beans, meaning they support dependency injection and AOP.

    Additionally, you can use custom annotations for parameter binding (e.g., @UserBind) to map objects to query parameters. These are detected automatically by JDBI without requiring a custom installer.

    @SqlUpdate("update users set version=:version, name=:name where id=:id and version=:version - 1")
    int update(@UserBind User entry);
  4. How classpath scanning works in Guicey

    master

    When auto-scan is enabled, Guicey performs the following steps:

    1. Search for Installers: It searches the classpath for classes implementing FeatureInstaller.
    2. Match Extensions: It uses the registered installers (via FeatureInstaller#matches) to identify extensions.
    3. Command Discovery: If .searchCommands() is enabled, it searches for all classes extending Command and installs them into the bootstrap.

    Technical Details:

    • Scope: It searches the specified packages and all their subpackages.
    • Exclusions: Abstract classes are automatically ignored.
    • Inner Classes: Static inner classes are resolved and detected (e.g., a @Provider static inner class within an abstract class).
  5. Register resources via interfaces

    master

    The ResourceInstaller recognizes a class as a REST resource if the @Path annotation is found on a directly implemented interface. This pattern is particularly useful when using Jersey client proxies to call remote resources.

    @Path("/res")
    @Produces("application/json")
    interface ResourceContract {
    
        @GET
        @Path("/sample")
        String sample();
    }
    
    class SampleResource implements ResourceContract {
    
        @Inject
        private MyService service;
    
        @Override
        public Response sample() {
            return Response.ok(service.result()).build();
        }
    }
  6. Monitor Heap Regions and GC Metrics

    master

    The JVM heap is divided into generations. Understanding how these appear in metrics depends on the GC algorithm in use:

    Serial GC

    When Serial GC is active (typically < 2GB memory), heap regions have fixed sizes. The Young generation (Eden + Survivor) is determined by MaxNewSize (defaulting to 1/3 of max heap). Within the Young generation, sizing is controlled by NewRatio and SurvivorRatio (defaults: 2 and 8 in OpenJDK).

    G1 GC

    In G1 GC, the sizes of Eden and Survivor spaces are adaptive and resized after every GC cycle. Metric Gotcha: In monitoring tools, the 'Max' values for Eden and Survivor spaces may appear as zero or -1 because they are not fixed. Do not be confused by this; the actual usage values will be non-zero.

  7. Project structure and modules

    master

    The project is organized into a core module and several extension modules:

    • ru.vyarus:dropwizard-guicey: The core Guicey module. This can be used standalone without any additional modules.
    • ru.vyarus.guicey:guicey-[module name]: Extension modules that provide additional functionality, such as integration with 3rd party libraries. These should be used with the ru.vyarus.guicey:guicey-bom Bill of Materials (BOM).

    For practical implementation details, refer to the various usage examples provided in the repository.

  8. Understand the Web Mappings Report state

    master

    The Web Mappings Report provides a diagnostic view of all registered web components (filters and servlets). It displays the hierarchy of mappings, the component type, the path, the implementation class, the bundle/module responsible, and its current operational state.

    Key states include:

    • STOPPED: The component is registered but not currently active.
    • [ERROR]: The component failed to start (often due to configuration or dependency issues).
    • [REQUEST]: Indicates the component is part of the request processing chain.
    • Disabled: A component that has been explicitly disabled (e.g., via setEnabled(false) on the ServletHandler) will appear as STOPPED in the report.
  9. How Admin REST works

    master

    The guicey-admin-rest module mirrors all resources into an admin context using a special servlet that redirects incoming requests into the Jersey context.

    This approach provides two main benefits:

    1. Security: Admin-only resources (marked with @AdminResource) are hidden from the user context (returning 404) but remain accessible in the admin context.
    2. Efficiency: It avoids the overhead of registering a completely separate Jersey context and simplifies the management of Jersey extensions.
  10. Understand the Startup Time report structure

    master

    The startup time report provides a hierarchical breakdown of time consumption. Key metrics include:

    • JVM time before: The time elapsed from JVM start until the application initialization began (obtained via MX bean).
    • Application startup: Total time for the initialization phase.
      • Dropwizard initialization: Time spent in the Dropwizard init phase.
      • GuiceBundle: Specific breakdown of Guice-related tasks like Classpath scan, Hooks processing, Commands processing, and Installers time.
    • Dropwizard run: Time spent in the Dropwizard run phase, including Configuration and Environment and GuiceBundle configuration analysis.

    Limitations:

    • The report cannot show initialization times for Dropwizard bundles registered before the GuiceBundle.
    • The Application#run method time is measured as part of the "web" phase, as the bundle cannot hook into that specific point.
    INFO  [2025-03-27 09:12:27,435] ru.vyarus.dropwizard.guice.debug.StartupTimeDiagnostic: Application startup time: 
    
    	JVM time before                    : 1055 ms
    
    	Application startup                : 807 ms
    		Dropwizard initialization          : 127 ms
    			GuiceBundle                        : 123 ms (finished since start at 127 ms)
    				Bundle builder time                : 38 ms
    				Hooks processing                   : 3.23 ms
    				Classpath scan                     : 44 ms
    				Commands processing                : 4.41 ms
    				Bundles lookup                     : 1.15 ms
    				Guicey bundles init                : 3.24 ms
    				Installers time                    : 21 ms
    				Listeners time                     : 1.35 ms
    
    	Dropwizard run                     : 679 ms
    		Configuration and Environment      : 483 ms
    		GuiceBundle                        : 196 ms
  11. Identify removed bindings in the Guice bindings report

    master

    When using dropwizard-guicey to disable specific extensions or modules, the Guice bindings report will explicitly mark these removals.

    • Use .disableExtensions(Class<?>) to disable specific extension bindings.
    • Use .disableModules(Class<?>) to disable entire Guice modules.

    In the diagnostic report output, removed bindings are indicated with the REMOVED tag. This allows you to verify that your configuration to disable specific components is working as expected.

    GuiceBundle.builder()
            .modules(new TransitiveModule())
            .disableExtensions(TransitiveModule.Res2)
            .disableModules(TransitiveModule.Inner)
            .printGuiceBindings()
            .build()