Hi everybody, I made some fixes to my ThreadFactory based on Spring TaskExecutor. Now, interrupt/join/terminate calls are forwarded to the wrapped WorkerTask. This way, threads close smoothly, without throwing errors.
I include my current code. Tested with SNMP4J 1.10.2 and Spring 2.5.6-SEC01. Comments and suggestions are welcome. Next post will be for TimerFactory with CommonJ integration. Regards package org.snmp4j.util.spring; import org.snmp4j.log.LogAdapter; import org.snmp4j.log.LogFactory; import org.snmp4j.util.ThreadFactory; import org.snmp4j.util.WorkerTask; import org.springframework.core.task.TaskExecutor; import org.springframework.util.Assert; /** * TreadFactory implementation based on Spring TaskExecutor. */ public class TaskExecutorThreadFactoryImpl implements ThreadFactory { /** * Logger. */ final static LogAdapter LOGGER = LogFactory .getLogger(TaskExecutorThreadFactoryImpl.class); /** * TaskExecutor. */ private TaskExecutor taskExecutor; /** * Set TaskExecutor. * * @param taskExecutor * a TaskExecutor. */ public void setTaskExecutor(TaskExecutor taskExecutor) { this.taskExecutor = taskExecutor; } /** * Constructor. */ public TaskExecutorThreadFactoryImpl() { } /* * (without Javadoc) * * @see org.snmp4j.util.ThreadFactory#createWorkerThread(java.lang.String, * org.snmp4j.util.WorkerTask, boolean) */ public WorkerTask createWorkerThread(String name, WorkerTask task, boolean daemon) { LOGGER.debug("Creating WorkerThread: " + name + " daemon: " + daemon); return new TaskExecutorWorkerTaskImpl(taskExecutor, name, task, daemon); } /** * Initialization. */ public void init() { Assert.notNull(taskExecutor, "taskExecutor is required."); } } package org.snmp4j.util.spring; import org.snmp4j.log.LogAdapter; import org.snmp4j.log.LogFactory; import org.snmp4j.util.WorkerTask; import org.springframework.core.task.TaskExecutor; import org.springframework.scheduling.SchedulingAwareRunnable; /** * WorkerTask implementation based on Spring TaskExecutor. */ public class TaskExecutorWorkerTaskImpl implements WorkerTask { /** * Logger. */ final static LogAdapter LOGGER = LogFactory .getLogger(TaskExecutorWorkerTaskImpl.class); /** * TaskExecutor. */ private TaskExecutor taskExecutor; /** * Name. */ private String name; /** * Worker task wrapper. */ private WorkerTaskWrapper workerTaskWrapper; /** * Constructor. * * @param taskExecutor * a task executor. * @param name * a name. * @param workerTask * a worker task. * @param daemon * true if daemon process, false otherwise. */ public TaskExecutorWorkerTaskImpl(TaskExecutor taskExecutor, String name, WorkerTask workerTask, boolean daemon) { this.taskExecutor = taskExecutor; this.name = name; this.workerTaskWrapper = new WorkerTaskWrapper(workerTask, daemon); } /* * (withoutJavadoc) * * @see org.snmp4j.util.WorkerTask#interrupt() */ public void interrupt() { LOGGER.debug("WorkerTask interrupt: " + this.name); workerTaskWrapper.workerTask.interrupt(); } /* * (withoutJavadoc) * * @see org.snmp4j.util.WorkerTask#join() */ public void join() throws InterruptedException { LOGGER.debug("WorkerTask join: " + this.name); workerTaskWrapper.workerTask.join(); } /* * (withoutJavadoc) * * @see org.snmp4j.util.WorkerTask#terminate() */ public void terminate() { LOGGER.debug("WorkerTask terminate: " + this.name); workerTaskWrapper.workerTask.terminate(); } /* * (withoutJavadoc) * * @see java.lang.Runnable#run() */ public void run() { LOGGER.debug("WorkerTask run: " + this.name); taskExecutor.execute(workerTaskWrapper); } /** * Wrapper for WorkerTask. * */ private class WorkerTaskWrapper implements SchedulingAwareRunnable { /** * Worker task. */ private WorkerTask workerTask; /** * True if daemon process, false otherwise. */ private boolean daemon; /** * Constructor. * * @param workerTask * a worker task. * @param daemon * true if daemon process, false otherwise. */ public WorkerTaskWrapper(WorkerTask workerTask, boolean daemon) { this.workerTask = workerTask; this.daemon = daemon; } /* * (without Javadoc) * * @see java.lang.Runnable#run() */ public void run() { workerTask.run(); } /* * (without Javadoc) * * @see org.springframework.scheduling.SchedulingAwareRunnable#isLongLived() */ public boolean isLongLived() { return daemon; } } } Extract from application context: <bean id="taskExecutor" class= "org.springframework.scheduling.commonj.WorkManagerTaskExecutor" p:workManagerName="yourWorkManagerReferenceName" p:resourceRef="true" /> <bean id="snmp4jThreadFactory" class= "org.snmp4j.util.spring.TaskExecutorThreadFactoryImpl" init-method="init" p:taskExecutor-ref="taskExecutor" /> You need a work manager defined in your application server, and a reference defined in your web.xml for it. _______________________________________________ SNMP4J mailing list SNMP4J@agentpp.org http://lists.agentpp.org/mailman/listinfo/snmp4j