Dropwizard utility classes for data sizes, durations, enums, generics, resources, exceptions, JAR locations, and direct execution services.
—
Utilities for JAR metadata extraction and direct task execution capabilities.
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.
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 frompublic 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:
Package.getImplementationVersion()Implementation-Version attributepublic String toString();Returns the name of the JAR file containing the class.
Returns:
"project.jar" as a fallback if the JAR name cannot be determined or if running from non-JAR sources (e.g., IDE, exploded directories)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");
}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...
}
}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;
}
}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")
));
}
}The DirectExecutorService is an implementation of ExecutorService that directly executes tasks on the calling thread if the service has not been shut down.
public DirectExecutorService();Creates a new DirectExecutorService instance.
public void execute(Runnable command);Executes the given command directly on the calling thread.
Parameters:
command - The runnable task to executeThrows:
RejectedExecutionException - If the executor has been shut downBehavior:
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.
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();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);
}
}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);
}
}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();
}
}
}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();
}
}
}
}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")
);
}
}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