CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-dropwizard--dropwizard-util

Dropwizard utility classes for data sizes, durations, enums, generics, resources, exceptions, JAR locations, and direct execution services.

Pending
Overview
Eval results
Files

jar-executor.mddocs/

JAR Location and Executor Services

Utilities for JAR metadata extraction and direct task execution capabilities.

JarLocation Class

The JarLocation class encapsulates the location on the local filesystem of the JAR file in which code is executing and provides access to JAR metadata.

Constructor

public JarLocation(Class<?> klass);

Constructs a new JarLocation object to access the code source for the specified class.

Parameters:

  • klass - The class to access the code source from

Version Information

public Optional<String> getVersion();

Returns the version of the JAR file containing the provided class.

Returns: An Optional<String> containing the implementation version from the JAR manifest, or empty if not available

Implementation Details:

  • Retrieves version from Package.getImplementationVersion()
  • Returns empty Optional if package information is not available
  • Version information comes from JAR manifest Implementation-Version attribute

JAR File Name

public String toString();

Returns the name of the JAR file containing the class.

Returns:

  • The JAR file name if the class is loaded from a JAR file
  • "project.jar" as a fallback if the JAR name cannot be determined or if running from non-JAR sources (e.g., IDE, exploded directories)

Usage Examples

Basic JAR Information

import io.dropwizard.util.JarLocation;
import java.util.Optional;

// Get information about the current application's JAR
JarLocation appLocation = new JarLocation(MyApplication.class);
String jarName = appLocation.toString();
Optional<String> version = appLocation.getVersion();

System.out.println("Running from JAR: " + jarName);
if (version.isPresent()) {
    System.out.println("Version: " + version.get());
} else {
    System.out.println("Version information not available");
}

Application Startup Information

public class ApplicationInfo {
    private final JarLocation location;
    private final String applicationName;
    
    public ApplicationInfo(Class<?> mainClass, String applicationName) {
        this.location = new JarLocation(mainClass);
        this.applicationName = applicationName;
    }
    
    public void printStartupInfo() {
        System.out.println("=== " + applicationName + " ===");
        System.out.println("JAR: " + location.toString());
        
        Optional<String> version = location.getVersion();
        if (version.isPresent()) {
            System.out.println("Version: " + version.get());
        } else {
            System.out.println("Version: Development");
        }
        
        System.out.println("Java: " + System.getProperty("java.version"));
        System.out.println("Started at: " + new java.util.Date());
    }
}

// Usage in main method
public class MyApplication {
    public static void main(String[] args) {
        ApplicationInfo info = new ApplicationInfo(MyApplication.class, "My Service");
        info.printStartupInfo();
        
        // Continue with application startup...
    }
}

Health Check Integration

public class ApplicationHealthCheck {
    private final JarLocation jarLocation;
    
    public ApplicationHealthCheck(Class<?> applicationClass) {
        this.jarLocation = new JarLocation(applicationClass);
    }
    
    public Map<String, Object> getHealthInfo() {
        Map<String, Object> health = new HashMap<>();
        health.put("status", "UP");
        health.put("jar", jarLocation.toString());
        
        Optional<String> version = jarLocation.getVersion();
        health.put("version", version.orElse("unknown"));
        
        return health;
    }
}

Logging and Monitoring

public class ApplicationMetrics {
    private static final Logger logger = LoggerFactory.getLogger(ApplicationMetrics.class);
    
    public static void logApplicationStart(Class<?> mainClass) {
        JarLocation location = new JarLocation(mainClass);
        
        logger.info("Application starting - JAR: {}, Version: {}", 
                   location.toString(), 
                   location.getVersion().orElse("development"));
                   
        // Send metrics to monitoring system
        sendMetric("app.start", Map.of(
            "jar", location.toString(),
            "version", location.getVersion().orElse("dev")
        ));
    }
}

DirectExecutorService Class

The DirectExecutorService is an implementation of ExecutorService that directly executes tasks on the calling thread if the service has not been shut down.

Constructor

public DirectExecutorService();

Creates a new DirectExecutorService instance.

Execution Methods

public void execute(Runnable command);

Executes the given command directly on the calling thread.

Parameters:

  • command - The runnable task to execute

Throws:

  • RejectedExecutionException - If the executor has been shut down

Behavior:

  • Executes the task immediately on the calling thread
  • Tracks running tasks for proper shutdown behavior
  • Rejects new tasks if the executor has been shut down

Lifecycle Methods

public void shutdown();
public List<Runnable> shutdownNow();
public boolean isShutdown();
public boolean isTerminated();
public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;

shutdown(): Initiates an orderly shutdown where previously submitted tasks continue to execute, but no new tasks are accepted.

shutdownNow(): Attempts to stop all actively executing tasks and returns an empty list (since tasks execute immediately, there are no queued tasks to return).

isShutdown(): Returns true if this executor has been shut down.

isTerminated(): Returns true if all tasks have completed following shut down and no tasks are currently running.

awaitTermination(): Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted.

Usage Examples

Basic Task Execution

import io.dropwizard.util.DirectExecutorService;
import java.util.concurrent.ExecutorService;

// Create executor
ExecutorService executor = new DirectExecutorService();

// Execute tasks (runs immediately on calling thread)
executor.execute(() -> System.out.println("Task 1 executed"));
executor.execute(() -> System.out.println("Task 2 executed"));
executor.execute(() -> {
    System.out.println("Task 3 starting");
    // Some work...
    System.out.println("Task 3 completed");
});

// Output appears immediately as tasks execute on calling thread
// Shutdown when done
executor.shutdown();

Testing and Synchronous Execution

public class TaskProcessor {
    private final ExecutorService executor;
    
    public TaskProcessor(ExecutorService executor) {
        this.executor = executor;
    }
    
    public void processItems(List<String> items) {
        for (String item : items) {
            executor.execute(() -> processItem(item));
        }
    }
    
    private void processItem(String item) {
        // Process the item
        System.out.println("Processing: " + item);
    }
}

// In tests, use DirectExecutorService for synchronous execution
@Test
public void testProcessItems() {
    DirectExecutorService directExecutor = new DirectExecutorService();
    TaskProcessor processor = new TaskProcessor(directExecutor);
    
    List<String> items = Arrays.asList("item1", "item2", "item3");
    processor.processItems(items);
    
    // All tasks have completed synchronously by this point
    // No need to wait for async completion in tests
    
    directExecutor.shutdown();
}

// In production, use a proper thread pool
@Component
public class ProductionTaskProcessor {
    @Bean
    public TaskProcessor taskProcessor() {
        ExecutorService threadPool = Executors.newFixedThreadPool(10);
        return new TaskProcessor(threadPool);
    }
}

Configuration-Driven Executor Selection

public class ExecutorFactory {
    public enum ExecutionMode {
        DIRECT,    // Use DirectExecutorService
        ASYNC,     // Use thread pool
        FORK_JOIN  // Use ForkJoinPool
    }
    
    public ExecutorService createExecutor(ExecutionMode mode, int threadCount) {
        switch (mode) {
            case DIRECT:
                return new DirectExecutorService();
            case ASYNC:
                return Executors.newFixedThreadPool(threadCount);
            case FORK_JOIN:
                return new ForkJoinPool(threadCount);
            default:
                throw new IllegalArgumentException("Unknown execution mode: " + mode);
        }
    }
}

// Usage in configuration
public class ServiceConfiguration {
    private ExecutionMode executionMode = ExecutionMode.ASYNC;
    private int threadCount = 10;
    
    public ExecutorService createExecutor() {
        ExecutorFactory factory = new ExecutorFactory();
        return factory.createExecutor(executionMode, threadCount);
    }
}

Graceful Shutdown

public class ManagedExecutorService {
    private final DirectExecutorService executor;
    private volatile boolean shutdownRequested = false;
    
    public ManagedExecutorService() {
        this.executor = new DirectExecutorService();
    }
    
    public void executeTask(Runnable task) {
        if (shutdownRequested) {
            throw new IllegalStateException("Service is shutting down");
        }
        
        executor.execute(task);
    }
    
    public void shutdown() {
        shutdownRequested = true;
        executor.shutdown();
    }
    
    public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
        return executor.awaitTermination(timeout, unit);
    }
    
    public void shutdownAndWait(long timeoutSeconds) {
        shutdown();
        
        try {
            boolean terminated = awaitTermination(timeoutSeconds, TimeUnit.SECONDS);
            if (!terminated) {
                System.err.println("Executor did not terminate within " + timeoutSeconds + " seconds");
                executor.shutdownNow();
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            executor.shutdownNow();
        }
    }
}

Development vs Production Patterns

public class ServiceManager {
    private final ExecutorService executor;
    private final boolean isDevelopment;
    
    public ServiceManager(boolean isDevelopment) {
        this.isDevelopment = isDevelopment;
        
        if (isDevelopment) {
            // Use DirectExecutorService for easier debugging
            this.executor = new DirectExecutorService();
        } else {
            // Use proper thread pool for production
            this.executor = Executors.newCachedThreadPool();
        }
    }
    
    public void submitTask(Runnable task) {
        executor.execute(task);
    }
    
    public void shutdown() {
        executor.shutdown();
        
        if (!isDevelopment) {
            // Only need to wait for async executors
            try {
                if (!executor.awaitTermination(30, TimeUnit.SECONDS)) {
                    executor.shutdownNow();
                }
            } catch (InterruptedException e) {
                executor.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
    }
}

Integration Patterns

JAR Location in Dropwizard Applications

public class DropwizardApplication extends Application<MyConfiguration> {
    
    @Override
    public void run(MyConfiguration configuration, Environment environment) throws Exception {
        // Log application info at startup
        JarLocation location = new JarLocation(getClass());
        log.info("Starting {} from JAR: {}, Version: {}", 
                getName(), 
                location.toString(), 
                location.getVersion().orElse("development"));
        
        // Add version info to health checks
        environment.healthChecks().register("version", new HealthCheck() {
            @Override
            protected Result check() throws Exception {
                return Result.healthy("Version: " + location.getVersion().orElse("dev"));
            }
        });
        
        // Add version endpoint
        environment.jersey().register(new VersionResource(location));
    }
}

@Path("/version")
public class VersionResource {
    private final JarLocation jarLocation;
    
    public VersionResource(JarLocation jarLocation) {
        this.jarLocation = jarLocation;
    }
    
    @GET
    public Map<String, String> getVersion() {
        return Map.of(
            "jar", jarLocation.toString(),
            "version", jarLocation.getVersion().orElse("development")
        );
    }
}

DirectExecutorService in Testing Framework

public class TestExecutorExtension implements BeforeEachCallback, AfterEachCallback {
    private DirectExecutorService executor;
    
    @Override
    public void beforeEach(ExtensionContext context) {
        executor = new DirectExecutorService();
        // Store in test context for injection
        context.getStore(ExtensionContext.Namespace.GLOBAL)
               .put("executor", executor);
    }
    
    @Override
    public void afterEach(ExtensionContext context) {
        if (executor != null) {
            executor.shutdown();
        }
    }
    
    public static DirectExecutorService getExecutor(ExtensionContext context) {
        return context.getStore(ExtensionContext.Namespace.GLOBAL)
                     .get("executor", DirectExecutorService.class);
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-io-dropwizard--dropwizard-util

docs

data-size.md

duration.md

enum-generics.md

index.md

jar-executor.md

resource-exception.md

tile.json