JNDI support for Eclipse Jetty web server including dependency injection, lifecycle management, JNDI resource binding, and database-backed security services
—
Complete annotation-based dependency injection system with lifecycle callback support for enterprise Java applications. Handles @Resource, @PostConstruct, and @PreDestroy annotations with full webapp context integration.
Performs dependency injection of JNDI resources into object fields and methods, supporting both field and method injection patterns with complete type safety.
class Injection {
// Field injection constructor
Injection(Class<?> clazz, Field field, Class<?> resourceType, String jndiName, String mappingName);
// Method injection constructor
Injection(Class<?> clazz, Method method, Class<?> arg, Class<?> resourceType, String jndiName, String mappingName);
// Generic target injection constructor
Injection(Class<?> clazz, String target, Class<?> resourceType, String jndiName, String mappingName);
// Perform injection into target object
void inject(Object injectable);
// Lookup the resource value from JNDI
Object lookupInjectedValue() throws NamingException;
// Query methods
Class<?> getTargetClass();
Class<?> getParamClass();
Class<?> getResourceClass();
String getJndiName();
String getMappingName();
boolean isField();
boolean isMethod();
Member getTarget();
}Usage Example:
// Field injection setup
Field dataSourceField = MyClass.class.getDeclaredField("dataSource");
Injection injection = new Injection(
MyClass.class,
dataSourceField,
DataSource.class,
"jdbc/MyDB",
"mappedName"
);
// Inject into an instance
MyClass instance = new MyClass();
injection.inject(instance);Manages collections of injections per class, providing centralized coordination of dependency injection across webapp contexts with thread-safe read operations.
class InjectionCollection {
// Constants
static final String INJECTION_COLLECTION = "org.eclipse.jetty.injectionCollection";
// Add injection to collection
void add(Injection injection);
// Retrieve injections for specific class
Set<Injection> getInjections(String className);
// Get specific field injection
Injection getInjection(String jndiName, Class<?> clazz, Field field);
// Get specific method injection
Injection getInjection(String jndiName, Class<?> clazz, Method method, Class<?> paramClass);
// Inject all applicable injections into object
void inject(Object injectable);
}Usage Example:
// Set up injection collection in webapp context
WebAppContext webapp = new WebAppContext();
InjectionCollection injections = new InjectionCollection();
webapp.setAttribute(InjectionCollection.INJECTION_COLLECTION, injections);
// Add injections for various classes
injections.add(dataSourceInjection);
injections.add(envEntryInjection);
// Inject into any compatible object
Object serviceInstance = new MyService();
injections.inject(serviceInstance);Manages PostConstruct and PreDestroy lifecycle callbacks with validation and execution coordination for enterprise application lifecycle management.
abstract class LifeCycleCallback {
// Constants
static final Object[] __EMPTY_ARGS = new Object[]{};
// Constructors
LifeCycleCallback(String className, String methodName);
LifeCycleCallback(Class<?> clazz, String methodName);
// Execute the callback
void callback(Object instance) throws SecurityException, NoSuchMethodException,
ClassNotFoundException, IllegalArgumentException, IllegalAccessException,
InvocationTargetException;
// Validate callback method constraints
abstract void validate(Class<?> clazz, Method m);
// Query methods
Class<?> getTargetClass();
String getTargetClassName();
String getMethodName();
Method getTarget();
// Utility method for finding methods
Method findMethod(Package pack, Class<?> clazz, String methodName, boolean checkInheritance);
}
class LifeCycleCallbackCollection {
// Constants
static final String LIFECYCLE_CALLBACK_COLLECTION = "org.eclipse.jetty.lifecyleCallbackCollection";
// Add callback to collection
void add(LifeCycleCallback callback);
// Execute PostConstruct callbacks
void callPostConstructCallback(Object o) throws Exception;
// Execute PreDestroy callbacks
void callPreDestroyCallback(Object o) throws Exception;
// Get callbacks for specific object
Set<LifeCycleCallback> getPostConstructCallbacks(Object o);
Set<LifeCycleCallback> getPreDestroyCallbacks(Object o);
// Get all callbacks
Collection<LifeCycleCallback> getPostConstructCallbacks();
Collection<LifeCycleCallback> getPreDestroyCallbacks();
// Read-only views
Map<String, Set<LifeCycleCallback>> getPostConstructCallbackMap();
Map<String, Set<LifeCycleCallback>> getPreDestroyCallbackMap();
}Handles @PostConstruct annotation callbacks with proper validation of method constraints including parameter restrictions and access modifiers.
class PostConstructCallback extends LifeCycleCallback {
// Constructors
PostConstructCallback(Class<?> clazz, String methodName);
PostConstructCallback(String className, String methodName);
// Validate PostConstruct method constraints
void validate(Class<?> clazz, Method method);
// Execute PostConstruct callback
void callback(Object instance);
}Usage Example:
// Set up PostConstruct callback
PostConstructCallback callback = new PostConstructCallback(MyService.class, "initialize");
// Add to collection
LifeCycleCallbackCollection callbacks = new LifeCycleCallbackCollection();
callbacks.add(callback);
// Execute on object creation
MyService service = new MyService();
callbacks.callPostConstructCallback(service);Handles @PreDestroy annotation callbacks with exception-safe execution and proper cleanup coordination for resource management.
class PreDestroyCallback extends LifeCycleCallback {
// Constructors
PreDestroyCallback(Class<?> clazz, String methodName);
PreDestroyCallback(String className, String methodName);
// Validate PreDestroy method constraints
void validate(Class<?> clazz, Method method);
// Execute PreDestroy callback (exception-safe)
void callback(Object instance);
}Usage Example:
// Set up PreDestroy callback
PreDestroyCallback callback = new PreDestroyCallback(MyService.class, "cleanup");
// Add to collection
LifeCycleCallbackCollection callbacks = new LifeCycleCallbackCollection();
callbacks.add(callback);
// Execute during object destruction
callbacks.callPreDestroyCallback(service);// Set up comprehensive annotation support in webapp
WebAppContext webapp = new WebAppContext();
// Configure injection collection
InjectionCollection injections = new InjectionCollection();
webapp.setAttribute(InjectionCollection.INJECTION_COLLECTION, injections);
// Configure lifecycle callbacks
LifeCycleCallbackCollection callbacks = new LifeCycleCallbackCollection();
webapp.setAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION, callbacks);
// Add field injection for DataSource
Field dsField = MyService.class.getDeclaredField("dataSource");
Injection dsInjection = new Injection(MyService.class, dsField, DataSource.class, "jdbc/MyDB", null);
injections.add(dsInjection);
// Add lifecycle callbacks
PostConstructCallback initCallback = new PostConstructCallback(MyService.class, "init");
PreDestroyCallback cleanupCallback = new PreDestroyCallback(MyService.class, "destroy");
callbacks.add(initCallback);
callbacks.add(cleanupCallback);
// Process service instance
MyService service = new MyService();
injections.inject(service); // Inject dependencies
callbacks.callPostConstructCallback(service); // Call @PostConstruct
// Later, during cleanup
callbacks.callPreDestroyCallback(service); // Call @PreDestroy// Discover and process injections for a class
InjectionCollection injections = (InjectionCollection)
webapp.getAttribute(InjectionCollection.INJECTION_COLLECTION);
// Get all injections for a specific class
Set<Injection> classInjections = injections.getInjections("com.example.MyService");
// Process each injection
for (Injection injection : classInjections) {
if (injection.isField()) {
System.out.println("Field injection: " + injection.getTarget());
} else if (injection.isMethod()) {
System.out.println("Method injection: " + injection.getTarget());
}
// Get the resource that will be injected
Object resource = injection.lookupInjectedValue();
System.out.println("Resource type: " + resource.getClass());
}For optimal performance in multi-threaded environments, configure all injections and callbacks during application startup before concurrent access begins.
Install with Tessl CLI
npx tessl i tessl/maven-org-eclipse-jetty--jetty-plus