You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@batchee.apache.org by rm...@apache.org on 2013/11/05 08:38:47 UTC

[10/62] Importing JBatch Reference Implementation from IBM. We'll fork it but this commit is to keep a track of what we forked.

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/f7740962/JSR352.Runtime/src/com/ibm/jbatch/container/api/impl/JobOperatorImpl.java
----------------------------------------------------------------------
diff --git a/JSR352.Runtime/src/com/ibm/jbatch/container/api/impl/JobOperatorImpl.java b/JSR352.Runtime/src/com/ibm/jbatch/container/api/impl/JobOperatorImpl.java
new file mode 100755
index 0000000..d903cda
--- /dev/null
+++ b/JSR352.Runtime/src/com/ibm/jbatch/container/api/impl/JobOperatorImpl.java
@@ -0,0 +1,495 @@
+/*
+ * Copyright 2012 International Business Machines Corp.
+ * 
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership. Licensed under the Apache License, 
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.ibm.jbatch.container.api.impl;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.batch.operations.JobExecutionAlreadyCompleteException;
+import javax.batch.operations.JobExecutionIsRunningException;
+import javax.batch.operations.JobExecutionNotMostRecentException;
+import javax.batch.operations.JobExecutionNotRunningException;
+import javax.batch.operations.JobOperator;
+import javax.batch.operations.JobRestartException;
+import javax.batch.operations.JobSecurityException;
+import javax.batch.operations.JobStartException;
+import javax.batch.operations.NoSuchJobException;
+import javax.batch.operations.NoSuchJobExecutionException;
+import javax.batch.operations.NoSuchJobInstanceException;
+import javax.batch.runtime.BatchStatus;
+import javax.batch.runtime.JobExecution;
+import javax.batch.runtime.JobInstance;
+import javax.batch.runtime.StepExecution;
+
+import com.ibm.jbatch.container.services.IBatchKernelService;
+import com.ibm.jbatch.container.services.IJobExecution;
+import com.ibm.jbatch.container.services.IJobStatusManagerService;
+import com.ibm.jbatch.container.services.IPersistenceManagerService;
+import com.ibm.jbatch.container.servicesmanager.ServicesManager;
+import com.ibm.jbatch.container.servicesmanager.ServicesManagerImpl;
+import com.ibm.jbatch.container.status.JobStatus;
+import com.ibm.jbatch.spi.BatchSecurityHelper;
+import com.ibm.jbatch.spi.services.IJobXMLLoaderService;
+
+
+public class JobOperatorImpl implements JobOperator {
+
+	private final static String sourceClass = JobOperatorImpl.class.getName();
+	private final static Logger logger = Logger.getLogger(sourceClass);
+
+	private ServicesManager servicesManager = null; 
+	private IBatchKernelService batchKernel = null;
+	private IPersistenceManagerService persistenceService = null;
+	private IJobXMLLoaderService jobXMLLoaderService = null;
+	private IJobStatusManagerService _jobStatusManagerService = null;
+
+	public JobOperatorImpl() {
+		servicesManager = ServicesManagerImpl.getInstance();
+		batchKernel = servicesManager.getBatchKernelService();
+		persistenceService = servicesManager.getPersistenceManagerService();
+		jobXMLLoaderService =  servicesManager.getDelegatingJobXMLLoaderService();
+		_jobStatusManagerService = servicesManager.getJobStatusManagerService();   
+	}
+
+	@Override
+	public long start(String jobXMLName, Properties jobParameters)	throws JobStartException, JobSecurityException {
+		long retVal = 0L;
+		/*
+		 * The whole point of this method is to have JobStartException serve as a blanket exception for anything other 
+		 * than the rest of the more specific exceptions declared on the throws clause.  So we won't log but just rethrow.
+		 */
+		try {
+			retVal = startInternal(jobXMLName, jobParameters);
+		} catch (JobSecurityException e) {
+			throw e;
+		} catch (Exception e) {
+			throw new JobStartException(e);
+		}
+		return retVal;
+	}
+	
+	private long startInternal(String jobXMLName, Properties jobParameters)	throws JobStartException, JobSecurityException {
+
+		StringWriter jobParameterWriter = new StringWriter();
+		if (jobParameters != null) {
+			try {
+				jobParameters.store(jobParameterWriter, "Job parameters on start: ");
+			} catch (IOException e) {
+				jobParameterWriter.write("Job parameters on start: not printable");
+			}
+		} else {
+			jobParameterWriter.write("Job parameters on start = null");
+		}
+
+		if (logger.isLoggable(Level.FINE)) {            
+			logger.fine("JobOperator start, with jobXMLName = " + jobXMLName + "\n" + jobParameterWriter.toString());
+		}
+
+		String jobXML = jobXMLLoaderService.loadJSL(jobXMLName);
+
+		long executionId = 0;
+
+		if (logger.isLoggable(Level.FINE)) {            
+			int concatLen = jobXML.length() > 200 ? 200 : jobXML.length();
+			logger.fine("Starting job: " + jobXML.substring(0, concatLen) + "... truncated ...");
+		}
+
+		IJobExecution execution = batchKernel.startJob(jobXML, jobParameters);
+		executionId = execution.getExecutionId();
+
+		if (logger.isLoggable(Level.FINE)) {
+			logger.fine("Started job with instanceId: " + execution.getInstanceId() + ", executionId: " + executionId);
+		}
+
+		return executionId;
+	}
+
+	@Override
+	public void abandon(long executionId)
+			throws NoSuchJobExecutionException, JobExecutionIsRunningException, JobSecurityException {
+
+		if (isAuthorized(persistenceService.getJobInstanceIdByExecutionId(executionId))) {
+			IJobExecution jobEx = persistenceService.jobOperatorGetJobExecution(executionId);
+
+			// if it is not in STARTED or STARTING state, mark it as ABANDONED
+			if (!(jobEx.getBatchStatus().equals(BatchStatus.STARTED) || jobEx.getBatchStatus().equals(BatchStatus.STARTING))){
+				// update table to reflect ABANDONED state
+				long time = System.currentTimeMillis();
+				Timestamp timestamp = new Timestamp(time);
+				persistenceService.updateBatchStatusOnly(jobEx.getExecutionId(), BatchStatus.ABANDONED, timestamp);
+				logger.fine("Job Execution: " + executionId + " was abandoned");
+
+				// Don't forget to update JOBSTATUS table
+				_jobStatusManagerService.updateJobBatchStatus(jobEx.getInstanceId(), BatchStatus.ABANDONED);
+			}
+			else {
+				logger.warning("Job Execution: " + executionId + " is still running");
+				throw new JobExecutionIsRunningException("Job Execution: " + executionId + " is still running");
+			}
+		} else {
+			throw new JobSecurityException("The current user is not authorized to perform this operation");
+		}
+
+	}
+
+	@Override
+	public IJobExecution getJobExecution(long executionId)
+			throws NoSuchJobExecutionException, JobSecurityException {
+		if (isAuthorized(persistenceService.getJobInstanceIdByExecutionId(executionId))) {
+			return batchKernel.getJobExecution(executionId);
+		} else {
+			throw new JobSecurityException("The current user is not authorized to perform this operation");
+		}
+	}
+
+	@Override
+	public List<JobExecution> getJobExecutions(JobInstance instance)
+			throws NoSuchJobInstanceException, JobSecurityException {
+		List<JobExecution> executions = new ArrayList<JobExecution>();
+
+		if (isAuthorized(instance.getInstanceId())) {
+			// Mediate between one 
+			List<IJobExecution> executionImpls = persistenceService.jobOperatorGetJobExecutions(instance.getInstanceId());
+			if (executionImpls.size() == 0 ){
+				logger.warning("The current user is not authorized to perform this operation");
+				throw new NoSuchJobInstanceException( "Job: " + instance.getJobName() + " does not exist");
+			}
+			for (IJobExecution e : executionImpls) {
+				executions.add(e);
+			}
+		} else {
+			logger.warning("The current user is not authorized to perform this operation");
+			throw new JobSecurityException("The current user is not authorized to perform this operation");
+		}
+
+		return executions;
+	}
+
+	@Override
+	public JobInstance getJobInstance(long executionId)
+			throws NoSuchJobExecutionException, JobSecurityException {
+		if (isAuthorized(persistenceService.getJobInstanceIdByExecutionId(executionId))) {
+			return this.batchKernel.getJobInstance(executionId);
+		} else {
+			throw new JobSecurityException("The current user is not authorized to perform this operation");
+		}
+	}
+
+	@Override
+	public int getJobInstanceCount(String jobName) throws NoSuchJobException, JobSecurityException {
+
+		int jobInstanceCount = 0;
+
+		BatchSecurityHelper helper = getBatchSecurityHelper();
+		
+		if (isCurrentTagAdmin(helper)) {
+			// Do an unfiltered query
+			jobInstanceCount = persistenceService.jobOperatorGetJobInstanceCount(jobName);
+		} else {
+			jobInstanceCount = persistenceService.jobOperatorGetJobInstanceCount(jobName, helper.getCurrentTag());
+		}
+
+		if (jobInstanceCount > 0) {
+			return jobInstanceCount;
+		}
+		else { 
+			logger.fine("getJobInstanceCount: Job Name " + jobName + " not found");
+			throw new NoSuchJobException( "Job " + jobName + " not found");
+		}
+	}
+
+	@Override
+	public List<JobInstance> getJobInstances(String jobName, int start,
+			int count) throws NoSuchJobException, JobSecurityException {
+
+		logger.entering(sourceClass, "getJobInstances", new Object[]{jobName, start, count});
+		List<JobInstance> jobInstances = new ArrayList<JobInstance>();
+
+		if (count == 0) {
+			return new ArrayList<JobInstance>();
+		} else if (count < 0) {
+			throw new IllegalArgumentException("Count should be a positive integer (or 0, which will return an empty list)");
+		}
+		
+		List<Long> instanceIds; 
+		BatchSecurityHelper helper = getBatchSecurityHelper();
+		if (isCurrentTagAdmin(helper)) {
+			// Do an unfiltered query
+			instanceIds	= persistenceService.jobOperatorGetJobInstanceIds(jobName, start, count);
+		} else {
+			instanceIds	= persistenceService.jobOperatorGetJobInstanceIds(jobName, helper.getCurrentTag(), start, count);
+		}
+
+		// get the jobinstance ids associated with this job name
+
+		if (instanceIds.size() > 0){
+			// for every job instance id
+			for (long id : instanceIds){
+				// get the job instance obj, add it to the list
+				JobStatus jobStatus = this._jobStatusManagerService.getJobStatus(id);
+				JobInstance jobInstance = jobStatus.getJobInstance();
+				logger.finest("Matched jobInstance = " + jobInstance.getInstanceId());
+				if(isAuthorized(jobInstance.getInstanceId())) {
+					logger.finest("Authorized so adding to list jobInstance =  " + jobInstance.getInstanceId());
+					jobInstances.add(jobInstance);	
+				}
+			}
+			// send the list of objs back to caller
+			logger.exiting(sourceClass, "getJobInstances", jobInstances);
+			return jobInstances;
+		} else {
+			logger.fine("getJobInstances: Job Name " + jobName + " not found");
+			throw new NoSuchJobException( "Job Name " + jobName + " not found");
+		}
+	}
+
+	/*
+	 * This should only be called by the "external" JobOperator API, since it filters
+	 * out the "subjob" parallel execution entries.
+	 */
+	@Override
+	public Set<String> getJobNames() throws JobSecurityException {
+
+		Set<String> jobNames = new HashSet<String>();
+		Map<Long, String> data = persistenceService.jobOperatorGetExternalJobInstanceData();
+		Iterator<Map.Entry<Long,String>> it = data.entrySet().iterator();
+		while (it.hasNext()) {
+			Map.Entry<Long,String> entry = it.next();
+			long instanceId = entry.getKey();
+			if(isAuthorized(instanceId)) {
+				String name = entry.getValue();
+				jobNames.add(name);
+			}
+		}
+		return jobNames;
+	}
+
+	@Override
+	public Properties getParameters(long executionId)
+			throws NoSuchJobExecutionException, JobSecurityException{
+
+		Properties props = null;
+		JobInstance requestedJobInstance = batchKernel.getJobInstance(executionId);
+
+		if (isAuthorized(requestedJobInstance.getInstanceId())) {
+			props = persistenceService.getParameters(executionId);
+		} else {
+			logger.warning("getParameters: The current user is not authorized to perform this operation");
+			throw new JobSecurityException("The current user is not authorized to perform this operation");
+		}
+
+		return props;
+	}
+
+
+	@Override
+	public List<Long> getRunningExecutions(String jobName)
+			throws NoSuchJobException, JobSecurityException {
+
+		logger.entering(sourceClass, "getRunningExecutions", jobName);
+		List<Long> jobExecutions = new ArrayList<Long>();
+
+		// get the jobexecution ids associated with this job name
+		Set<Long> executionIds = persistenceService.jobOperatorGetRunningExecutions(jobName);
+
+		if (executionIds.size() > 0){
+			// for every job instance id
+			for (long id : executionIds){
+				try {
+					logger.finer("Examining executionId: " + id);
+					if(isAuthorized(persistenceService.getJobInstanceIdByExecutionId(id))) {
+						if (batchKernel.isExecutionRunning(id)) {
+							IJobExecution jobEx = batchKernel.getJobExecution(id);
+							jobExecutions.add(jobEx.getExecutionId());
+						} else {
+							logger.finer("Found executionId: " + id + " with a BatchStatus indicating running, but kernel doesn't currently have an entry for this execution in the kernel's in-memory map.");
+						}
+					} else {
+						logger.finer("Don't have authorization for executionId: " + id);
+					}
+				} catch (NoSuchJobExecutionException e) {
+					String errorMsg = "Just found execution with id = " + id + " in table, but now seeing it as gone";
+					logger.severe(errorMsg);
+					throw new IllegalStateException(errorMsg, e);
+				}
+			}
+			// send the list of objs back to caller
+			logger.exiting(sourceClass, "getRunningExecutions", jobExecutions);
+			return jobExecutions;
+		}
+		else { 
+			logger.fine("getRunningExecutions: Job Name " + jobName + " not found");
+			throw new NoSuchJobException( "Job Name " + jobName + " not found");
+		}
+	}
+
+	@Override
+	public List<StepExecution> getStepExecutions(long executionId)
+			throws NoSuchJobExecutionException, JobSecurityException {
+
+		logger.entering(sourceClass, "getStepExecutions", executionId);
+
+		List<StepExecution> stepExecutions = new ArrayList<StepExecution>();
+
+		IJobExecution jobEx = batchKernel.getJobExecution(executionId);
+		if (jobEx == null){
+			logger.fine("Job Execution: " + executionId + " not found");
+			throw new NoSuchJobExecutionException("Job Execution: " + executionId + " not found");
+		}
+		if (isAuthorized(persistenceService.getJobInstanceIdByExecutionId(executionId))) {
+			stepExecutions = persistenceService.getStepExecutionsForJobExecution(executionId);
+		} else {
+			logger.warning("getStepExecutions: The current user is not authorized to perform this operation");
+			throw new JobSecurityException("The current user is not authorized to perform this operation");
+		}
+
+		logger.exiting(sourceClass, "getStepExecutions", stepExecutions);
+		return stepExecutions;
+
+	}
+
+	@Override
+	public long restart(long oldExecutionId, Properties restartParameters) throws JobExecutionAlreadyCompleteException,
+	NoSuchJobExecutionException, JobExecutionNotMostRecentException, JobRestartException, JobSecurityException {
+		/*
+		 * The whole point of this method is to have JobRestartException serve as a blanket exception for anything other 
+		 * than the rest of the more specific exceptions declared on the throws clause.  So we won't log but just rethrow.
+		 */
+		long retVal = 0L;
+		try {
+			retVal = restartInternal(oldExecutionId, restartParameters);
+		} catch (JobExecutionAlreadyCompleteException e) {
+			throw e;
+		} catch (NoSuchJobExecutionException e) {
+			throw e;
+		} catch (JobExecutionNotMostRecentException e) {
+			throw e; 
+		} catch (JobSecurityException e) {
+			throw e; 
+		} catch (Exception e) {
+			throw new JobRestartException(e);
+		}
+		
+		return retVal;
+	}
+	
+	private long restartInternal(long oldExecutionId, Properties restartParameters) throws JobExecutionAlreadyCompleteException,
+	NoSuchJobExecutionException, JobExecutionNotMostRecentException, JobRestartException, JobSecurityException {
+		long newExecutionId = -1;
+
+		if (isAuthorized(persistenceService.getJobInstanceIdByExecutionId(oldExecutionId))) {
+			StringWriter jobParameterWriter = new StringWriter();
+			if (restartParameters != null) {
+				try {
+					restartParameters.store(jobParameterWriter, "Job parameters on restart: ");
+				} catch (IOException e) {
+					jobParameterWriter.write("Job parameters on restart: not printable");
+				}
+			} else {
+				jobParameterWriter.write("Job parameters on restart = null");
+			}
+
+			if (logger.isLoggable(Level.FINE)) {            
+				logger.fine("JobOperator restart, with old executionId = " + oldExecutionId + "\n" + jobParameterWriter.toString());
+			}
+
+			IJobExecution execution = batchKernel.restartJob(oldExecutionId, restartParameters);
+
+			newExecutionId = execution.getExecutionId();
+
+			if (logger.isLoggable(Level.FINE)) {            
+				logger.fine("Restarted job with instanceID: " + execution.getInstanceId() + ", new executionId: " + newExecutionId + ", and old executionID: " + oldExecutionId);
+			}
+		} else {
+			throw new JobSecurityException("The current user is not authorized to perform this operation");
+		}
+
+		return newExecutionId;
+	}
+
+	@Override
+	public void stop(long executionId) throws NoSuchJobExecutionException,
+	JobExecutionNotRunningException, JobSecurityException {
+
+		logger.entering(sourceClass, "stop", executionId);
+
+		if (isAuthorized(persistenceService.getJobInstanceIdByExecutionId(executionId))) {
+			batchKernel.stopJob(executionId);
+		} else {
+			throw new JobSecurityException("The current user is not authorized to perform this operation");
+		}
+
+		logger.exiting(sourceClass, "stop");
+	}
+
+	public void purge(String apptag) {
+		BatchSecurityHelper bsh = getBatchSecurityHelper();
+		if (isCurrentTagAdmin(bsh)) {
+			logger.finer("Current tag is admin, so authorized to purge.");
+			persistenceService.purge(apptag);
+		} else if (bsh.getCurrentTag().equals(apptag)) {
+			logger.finer("Current tag is the tag of record so authorized to purge.");
+			persistenceService.purge(apptag);
+		} else {
+			logger.finer("Current tag does not match the tag of record so will not purge.");
+		}
+	}
+
+	private boolean isAuthorized(long instanceId) {
+		logger.entering(sourceClass, "isAuthorized", instanceId);
+		boolean retVal = false;
+		
+		String apptag = persistenceService.getJobCurrentTag(instanceId);
+		
+		BatchSecurityHelper bsh = getBatchSecurityHelper();
+		if (isCurrentTagAdmin(bsh)) {
+			logger.finer("Current tag is admin, so always authorized");
+			retVal = true;
+		} else if (bsh.getCurrentTag().equals(apptag)) { 
+			logger.finer("Current tag is the tag of record");
+			retVal = true;
+		} else {
+			logger.finer("Current tag does not match the tag of record");
+			retVal = false;
+		}
+		
+		logger.exiting(sourceClass, "isAuthorized", retVal);
+		return retVal;
+	}
+
+	private boolean isCurrentTagAdmin(BatchSecurityHelper helper) {
+		return helper.isAdmin(helper.getCurrentTag());
+	}
+	
+	private BatchSecurityHelper getBatchSecurityHelper() {
+		BatchSecurityHelper bsh = batchKernel.getBatchSecurityHelper();
+		if (bsh == null) {
+			throw new IllegalStateException("Expect to have a security helper, at least the NoOp security helper.");
+		}
+		return bsh;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/f7740962/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/AbstractProxy.java
----------------------------------------------------------------------
diff --git a/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/AbstractProxy.java b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/AbstractProxy.java
new file mode 100755
index 0000000..3c7b11f
--- /dev/null
+++ b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/AbstractProxy.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2012 International Business Machines Corp.
+ * 
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership. Licensed under the Apache License, 
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package com.ibm.jbatch.container.artifact.proxy;
+
+import java.util.logging.Logger;
+
+import com.ibm.jbatch.container.context.impl.StepContextImpl;
+
+/**
+ * An abstract class which contains the common behavior for a batch artifact
+ * proxy. This class performs runtime introspection of an artifact instances
+ * annotations and handles property injection.
+ * 
+ */
+public abstract class AbstractProxy<T> {
+
+    private final static String sourceClass = AbstractProxy.class.getName();
+    private final static Logger logger = Logger.getLogger(sourceClass);
+
+    protected T delegate;
+    protected StepContextImpl stepContext;
+
+    /**
+     * @param delegate
+     *            An instance of a batch artifact which will back this proxy
+     * @param props
+     *            The properties directly associated with this batch artifact.
+     *            These properties will be injected into fields annotated with
+     *            the @BatchProperty annotation in the delegate object.
+     */
+    AbstractProxy(T delegate) {
+        this.delegate = delegate;
+    }
+
+    public T getDelegate() {
+        return this.delegate;
+    }
+    
+    public void setStepContext(StepContextImpl stepContext){
+    	this.stepContext = stepContext;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/f7740962/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/BatchletProxy.java
----------------------------------------------------------------------
diff --git a/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/BatchletProxy.java b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/BatchletProxy.java
new file mode 100755
index 0000000..5b0ecd5
--- /dev/null
+++ b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/BatchletProxy.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2012 International Business Machines Corp.
+ * 
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership. Licensed under the Apache License, 
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package com.ibm.jbatch.container.artifact.proxy;
+
+import javax.batch.api.Batchlet;
+
+import com.ibm.jbatch.container.exception.BatchContainerRuntimeException;
+
+public class BatchletProxy extends AbstractProxy<Batchlet> implements Batchlet {
+
+    BatchletProxy(Batchlet delegate) {
+        super(delegate);
+
+    }
+
+    @Override
+    public String process() {
+        try {
+            return this.delegate.process();
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+        
+
+    }
+
+    @Override
+    public void stop() {
+        try {
+            this.delegate.stop();
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+     
+    }
+
+
+
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/f7740962/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/CheckpointAlgorithmProxy.java
----------------------------------------------------------------------
diff --git a/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/CheckpointAlgorithmProxy.java b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/CheckpointAlgorithmProxy.java
new file mode 100755
index 0000000..cf6e393
--- /dev/null
+++ b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/CheckpointAlgorithmProxy.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2012 International Business Machines Corp.
+ * 
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership. Licensed under the Apache License, 
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package com.ibm.jbatch.container.artifact.proxy;
+
+import javax.batch.api.chunk.CheckpointAlgorithm;
+
+import com.ibm.jbatch.container.exception.BatchContainerRuntimeException;
+import com.ibm.jbatch.container.persistence.ItemCheckpointAlgorithm;
+
+public class CheckpointAlgorithmProxy extends AbstractProxy<CheckpointAlgorithm> implements CheckpointAlgorithm {
+
+    private String checkpointType = null;
+    private String checkpointName = null;
+
+    /*
+     * Allow this to be public as a special case so we can easily treat the built-in algorithms
+     * as identical to custom ones.
+     */
+    public CheckpointAlgorithmProxy(final CheckpointAlgorithm delegate) {
+        super(delegate);
+
+        if (delegate instanceof ItemCheckpointAlgorithm) {
+            checkpointType = "item";
+            checkpointName = ItemCheckpointAlgorithm.class.getName();
+        } else {
+			checkpointType = "custom";
+			checkpointName = delegate.getClass().getName();
+        }
+
+    }
+
+
+    public String getCheckpointType() {
+        return checkpointType;
+    }
+
+    public String getCheckpointAlgorithmClassName() {
+        return checkpointName;
+    }
+
+
+    @Override
+    public void beginCheckpoint() {
+        try {
+            this.delegate.beginCheckpoint();
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+
+    @Override
+    public int checkpointTimeout() {
+        try {
+            return this.delegate.checkpointTimeout();
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+
+    @Override
+    public void endCheckpoint() {
+        try {
+             this.delegate.endCheckpoint();
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+
+    @Override
+    public boolean isReadyToCheckpoint() {
+        try {
+            return this.delegate.isReadyToCheckpoint();
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/f7740962/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ChunkListenerProxy.java
----------------------------------------------------------------------
diff --git a/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ChunkListenerProxy.java b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ChunkListenerProxy.java
new file mode 100755
index 0000000..a0b9644
--- /dev/null
+++ b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ChunkListenerProxy.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2012 International Business Machines Corp.
+ * 
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership. Licensed under the Apache License, 
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package com.ibm.jbatch.container.artifact.proxy;
+
+import javax.batch.api.chunk.listener.ChunkListener;
+
+import com.ibm.jbatch.container.exception.BatchContainerRuntimeException;
+
+public class ChunkListenerProxy extends AbstractProxy<ChunkListener> implements ChunkListener {
+
+    ChunkListenerProxy(final ChunkListener delegate) {
+        super(delegate);
+
+    }
+
+
+    @Override
+    public void afterChunk() throws Exception {
+        try {
+            this.delegate.afterChunk();
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }        
+    }
+
+    @Override
+    public void beforeChunk() throws Exception {
+        try {
+            this.delegate.beforeChunk();
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }        
+    }
+
+    @Override
+    public void onError(Exception ex) throws Exception {
+        try {
+            this.delegate.onError(ex);
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }        
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/f7740962/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/DeciderProxy.java
----------------------------------------------------------------------
diff --git a/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/DeciderProxy.java b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/DeciderProxy.java
new file mode 100755
index 0000000..0c4e9d7
--- /dev/null
+++ b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/DeciderProxy.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2012 International Business Machines Corp.
+ * 
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership. Licensed under the Apache License, 
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.ibm.jbatch.container.artifact.proxy;
+
+import javax.batch.api.Decider;
+import javax.batch.runtime.StepExecution;
+
+import com.ibm.jbatch.container.exception.BatchContainerRuntimeException;
+
+public class DeciderProxy extends AbstractProxy<Decider> implements Decider {
+
+    DeciderProxy(Decider delegate) {
+        super(delegate);
+
+    }
+
+	@Override
+	public String decide(StepExecution[] stepExecutions) {
+		try {
+			return delegate.decide(stepExecutions);
+		} catch (Exception e) {
+			throw new BatchContainerRuntimeException(e);
+		}
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/f7740962/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/InjectionReferences.java
----------------------------------------------------------------------
diff --git a/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/InjectionReferences.java b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/InjectionReferences.java
new file mode 100755
index 0000000..7de9798
--- /dev/null
+++ b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/InjectionReferences.java
@@ -0,0 +1,64 @@
+/**
+ * Copyright 2013 International Business Machines Corp.
+ *
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership. Licensed under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.ibm.jbatch.container.artifact.proxy;
+
+import java.util.List;
+
+import javax.batch.runtime.context.JobContext;
+import javax.batch.runtime.context.StepContext;
+
+import com.ibm.jbatch.jsl.model.Property;
+
+
+
+/**
+ * This is a container class that holds on to the property and context injections
+ * that should be injected into a batch artifact. 
+ * 
+ */
+public class InjectionReferences {
+
+    private final JobContext jobContext;
+    private final StepContext stepContext;
+    
+    private List<Property> props;
+    
+    public InjectionReferences(JobContext jobContext, StepContext stepContext, 
+            List<Property> props) {
+
+        this.jobContext = jobContext;
+        this.stepContext = stepContext;
+        this.props = props;
+    }
+
+    public JobContext getJobContext() {
+        return jobContext;
+    }
+
+    public StepContext getStepContext() {
+        return stepContext;
+    }
+
+    public List<Property> getProps() {
+        return props;
+    }
+
+    public void setProps(List<Property> props) {
+        this.props = props;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/f7740962/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemProcessListenerProxy.java
----------------------------------------------------------------------
diff --git a/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemProcessListenerProxy.java b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemProcessListenerProxy.java
new file mode 100755
index 0000000..ece325b
--- /dev/null
+++ b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemProcessListenerProxy.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2012 International Business Machines Corp.
+ * 
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership. Licensed under the Apache License, 
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.ibm.jbatch.container.artifact.proxy;
+
+import javax.batch.api.chunk.listener.ItemProcessListener;
+
+import com.ibm.jbatch.container.exception.BatchContainerRuntimeException;
+
+public class ItemProcessListenerProxy extends AbstractProxy<ItemProcessListener> implements ItemProcessListener {
+
+    ItemProcessListenerProxy(ItemProcessListener delegate) {
+        super(delegate);
+
+    }
+
+    @Override
+    public void afterProcess(Object item, Object result) {
+        try {
+            this.delegate.afterProcess(item, result);
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+        
+
+    }
+
+    @Override
+    public void beforeProcess(Object item) {
+        try {
+            this.delegate.beforeProcess(item);
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+    @Override
+    public void onProcessError(Object item, Exception ex) {
+        try {
+            this.delegate.onProcessError(item, ex);
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/f7740962/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemProcessorProxy.java
----------------------------------------------------------------------
diff --git a/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemProcessorProxy.java b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemProcessorProxy.java
new file mode 100755
index 0000000..fc21c91
--- /dev/null
+++ b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemProcessorProxy.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2012 International Business Machines Corp.
+ * 
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership. Licensed under the Apache License, 
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.ibm.jbatch.container.artifact.proxy;
+
+import javax.batch.api.chunk.ItemProcessor;
+
+public class ItemProcessorProxy  extends AbstractProxy<ItemProcessor> implements ItemProcessor {
+
+	ItemProcessorProxy(ItemProcessor delegate) { 
+		super(delegate);
+	}
+
+	/*
+	 * In order to provide skip/retry logic, these exceptions
+	 * are thrown as-is rather than beeing wrapped.
+	 * @see javax.batch.api.ItemReader#readItem()
+	 */
+	@Override
+	public Object processItem(Object item) throws Exception {
+		return this.delegate.processItem(item);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/f7740962/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemReadListenerProxy.java
----------------------------------------------------------------------
diff --git a/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemReadListenerProxy.java b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemReadListenerProxy.java
new file mode 100755
index 0000000..cd49c38
--- /dev/null
+++ b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemReadListenerProxy.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2012 International Business Machines Corp.
+ * 
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership. Licensed under the Apache License, 
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package com.ibm.jbatch.container.artifact.proxy;
+
+import javax.batch.api.chunk.listener.ItemReadListener;
+
+import com.ibm.jbatch.container.exception.BatchContainerRuntimeException;
+
+public class ItemReadListenerProxy extends AbstractProxy<ItemReadListener> implements ItemReadListener{
+
+    ItemReadListenerProxy(ItemReadListener delegate) { 
+        super(delegate);
+    }
+
+    @Override
+    public void afterRead(Object item) {
+        
+        try {
+            this.delegate.afterRead(item);
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+    @Override
+    public void beforeRead() {
+     
+        try {
+            this.delegate.beforeRead();
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+    @Override
+    public void onReadError(Exception ex) {
+        
+        try {
+            this.delegate.onReadError(ex);
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/f7740962/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemReaderProxy.java
----------------------------------------------------------------------
diff --git a/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemReaderProxy.java b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemReaderProxy.java
new file mode 100755
index 0000000..8dc1b5c
--- /dev/null
+++ b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemReaderProxy.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2012 International Business Machines Corp.
+ * 
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership. Licensed under the Apache License, 
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package com.ibm.jbatch.container.artifact.proxy;
+
+import java.io.Serializable;
+
+import javax.batch.api.chunk.ItemReader;
+
+import com.ibm.jbatch.container.exception.BatchContainerRuntimeException;
+
+public class ItemReaderProxy extends AbstractProxy<ItemReader> implements ItemReader {
+
+    ItemReaderProxy(ItemReader delegate) {
+        super(delegate);
+    }
+
+    @Override
+    public Serializable checkpointInfo() {
+        try {
+            return this.delegate.checkpointInfo();
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+    @Override
+    public void close() {
+        try {
+            this.delegate.close();
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+    @Override
+    public void open(Serializable checkpoint) {
+        try {
+            this.delegate.open(checkpoint);
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+    /*
+     * In order to provide skip/retry logic, these exceptions
+     * are thrown as-is rather than beeing wrapped.
+     * @see javax.batch.api.ItemReader#readItem()
+     */
+    @Override
+    public Object readItem() throws Exception {
+		return this.delegate.readItem();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/f7740962/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemWriteListenerProxy.java
----------------------------------------------------------------------
diff --git a/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemWriteListenerProxy.java b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemWriteListenerProxy.java
new file mode 100755
index 0000000..1326d67
--- /dev/null
+++ b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemWriteListenerProxy.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2012 International Business Machines Corp.
+ * 
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership. Licensed under the Apache License, 
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package com.ibm.jbatch.container.artifact.proxy;
+
+import java.util.List;
+
+import javax.batch.api.chunk.listener.ItemWriteListener;
+
+import com.ibm.jbatch.container.exception.BatchContainerRuntimeException;
+
+public class ItemWriteListenerProxy extends AbstractProxy<ItemWriteListener> implements ItemWriteListener { 
+
+
+    ItemWriteListenerProxy(ItemWriteListener delegate) {
+        super(delegate);
+    }
+
+    @Override
+    public void afterWrite(List items) {
+        
+        try {
+            this.delegate.afterWrite(items);
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+    @Override
+    public void beforeWrite(List items) {
+        
+        try {
+            this.delegate.beforeWrite(items);
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+    @Override
+    public void onWriteError(List items, Exception ex) {
+        
+        
+        try {
+            this.delegate.onWriteError(items, ex);
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/f7740962/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemWriterProxy.java
----------------------------------------------------------------------
diff --git a/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemWriterProxy.java b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemWriterProxy.java
new file mode 100755
index 0000000..2ca6cc5
--- /dev/null
+++ b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ItemWriterProxy.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2012 International Business Machines Corp.
+ * 
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership. Licensed under the Apache License, 
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package com.ibm.jbatch.container.artifact.proxy;
+
+import java.io.Serializable;
+import java.util.List;
+
+import javax.batch.api.chunk.ItemWriter;
+
+import com.ibm.jbatch.container.exception.BatchContainerRuntimeException;
+
+public class ItemWriterProxy extends AbstractProxy<ItemWriter> implements ItemWriter {
+
+    ItemWriterProxy(ItemWriter delegate) {     	
+        super(delegate);
+   }
+
+    @Override
+    public Serializable checkpointInfo() {
+        
+        try {
+            return this.delegate.checkpointInfo();
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+    @Override
+    public void close() {
+        try {
+            this.delegate.close();
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+    @Override
+    public void open(Serializable checkpoint) {
+        try {
+            this.delegate.open(checkpoint);
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+    
+    /*
+     * In order to provide skip/retry logic, these exceptions
+     * are thrown as-is rather than beeing wrapped.
+     * @see javax.batch.api.ItemReader#readItem()
+     */
+    @Override
+    public void writeItems(List items) throws Exception{
+            this.delegate.writeItems(items);
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/f7740962/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/JobListenerProxy.java
----------------------------------------------------------------------
diff --git a/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/JobListenerProxy.java b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/JobListenerProxy.java
new file mode 100755
index 0000000..ffc452c
--- /dev/null
+++ b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/JobListenerProxy.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2012 International Business Machines Corp.
+ * 
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership. Licensed under the Apache License, 
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.ibm.jbatch.container.artifact.proxy;
+
+import javax.batch.api.listener.JobListener;
+
+import com.ibm.jbatch.container.exception.BatchContainerRuntimeException;
+
+public class JobListenerProxy extends AbstractProxy<JobListener> implements JobListener {
+
+    JobListenerProxy(JobListener delegate) {
+        super(delegate);
+    }
+
+    @Override
+    public void afterJob() {
+
+        try {
+            this.delegate.afterJob();
+        } catch (Exception e) {
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+    @Override
+    public void beforeJob() {
+
+        try {
+            this.delegate.beforeJob();
+        } catch (Exception e) {
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/f7740962/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ListenerFactory.java
----------------------------------------------------------------------
diff --git a/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ListenerFactory.java b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ListenerFactory.java
new file mode 100755
index 0000000..993b866
--- /dev/null
+++ b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ListenerFactory.java
@@ -0,0 +1,375 @@
+/*
+ * Copyright 2012 International Business Machines Corp.
+ * 
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership. Licensed under the Apache License, 
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.ibm.jbatch.container.artifact.proxy;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.batch.api.chunk.listener.ChunkListener;
+import javax.batch.api.chunk.listener.ItemProcessListener;
+import javax.batch.api.chunk.listener.ItemReadListener;
+import javax.batch.api.chunk.listener.ItemWriteListener;
+import javax.batch.api.chunk.listener.RetryProcessListener;
+import javax.batch.api.chunk.listener.RetryReadListener;
+import javax.batch.api.chunk.listener.RetryWriteListener;
+import javax.batch.api.chunk.listener.SkipProcessListener;
+import javax.batch.api.chunk.listener.SkipReadListener;
+import javax.batch.api.chunk.listener.SkipWriteListener;
+import javax.batch.api.listener.JobListener;
+import javax.batch.api.listener.StepListener;
+
+import com.ibm.jbatch.container.context.impl.StepContextImpl;
+import com.ibm.jbatch.jsl.model.JSLJob;
+import com.ibm.jbatch.jsl.model.Listener;
+import com.ibm.jbatch.jsl.model.Listeners;
+import com.ibm.jbatch.jsl.model.Property;
+import com.ibm.jbatch.jsl.model.Step;
+
+
+public class ListenerFactory {
+
+    private List<ListenerInfo> jobLevelListenerInfo = null;
+
+    private Map<String, List<ListenerInfo>> stepLevelListenerInfo = new HashMap<String, List<ListenerInfo>>();
+
+    /*
+     * Build job-level ListenerInfo(s) up-front, but build step-level ones
+     * lazily.
+     */
+    public ListenerFactory(JSLJob jobModel, InjectionReferences injectionRefs) {
+        initJobLevelListeners(jobModel, injectionRefs);
+    }
+
+    private void initJobLevelListeners(JSLJob jobModel, InjectionReferences injectionRefs) {
+        jobLevelListenerInfo = new ArrayList<ListenerInfo>();
+
+        Listeners jobLevelListeners = jobModel.getListeners();
+
+        if (jobLevelListeners != null) {
+            for (Listener listener : jobLevelListeners.getListenerList()) {
+                ListenerInfo info = buildListenerInfo(listener, injectionRefs);
+                jobLevelListenerInfo.add(info);
+            }
+        }
+    }
+
+    /*
+     * Does NOT throw an exception if a step-level listener is annotated with
+     * 
+     * @JobListener, even if that is the only type of listener annotation found.
+     */
+    private synchronized List<ListenerInfo> getStepListenerInfo(Step step, InjectionReferences injectionRefs) {
+        if (!stepLevelListenerInfo.containsKey(step.getId())) {
+            List<ListenerInfo> stepListenerInfoList = new ArrayList<ListenerInfo>();
+            stepLevelListenerInfo.put(step.getId(), stepListenerInfoList);
+
+            Listeners stepLevelListeners = step.getListeners();
+            if (stepLevelListeners != null) {
+                for (Listener listener : stepLevelListeners.getListenerList()) {
+                    ListenerInfo info = buildListenerInfo(listener, injectionRefs);
+                    stepListenerInfoList.add(info);
+                }
+            }
+
+            return stepListenerInfoList;
+        } else {
+            return stepLevelListenerInfo.get(step.getId());
+        }
+    }
+
+    private ListenerInfo buildListenerInfo(Listener listener, InjectionReferences injectionRefs) {
+
+        String id = listener.getRef();
+
+        List<Property> propList = (listener.getProperties() == null) ? null : listener.getProperties().getPropertyList();
+
+        injectionRefs.setProps(propList);
+        Object listenerArtifact = ProxyFactory.loadArtifact(id, injectionRefs);
+        if (listenerArtifact == null) {
+            throw new IllegalArgumentException("Load of artifact id: " + id + " returned <null>.");
+        }
+        ListenerInfo info = new ListenerInfo(listenerArtifact, propList);
+        return info;
+
+    }
+
+    public List<JobListenerProxy> getJobListeners() {
+        List<JobListenerProxy> retVal = new ArrayList<JobListenerProxy>();
+        for (ListenerInfo li : jobLevelListenerInfo) {
+            if (li.isJobListener()) {
+                JobListenerProxy proxy = new JobListenerProxy((JobListener) li.getArtifact());
+                retVal.add(proxy);
+            }
+        }
+        return retVal;
+    }
+
+    public List<ChunkListenerProxy> getChunkListeners(Step step, InjectionReferences injectionRefs, StepContextImpl stepContext) {
+
+        List<ListenerInfo> stepListenerInfo = getStepListenerInfo(step, injectionRefs);
+
+        List<ChunkListenerProxy> retVal = new ArrayList<ChunkListenerProxy>();
+
+        for (ListenerInfo li : stepListenerInfo) {
+            if (li.isChunkListener()) {
+                ChunkListenerProxy proxy = new ChunkListenerProxy((ChunkListener) li.getArtifact());
+                proxy.setStepContext(stepContext);
+                retVal.add(proxy);
+            }
+        }
+
+        return retVal;
+    }
+
+    public List<ItemProcessListenerProxy> getItemProcessListeners(Step step, InjectionReferences injectionRefs, StepContextImpl stepContext) {
+
+        List<ListenerInfo> stepListenerInfo = getStepListenerInfo(step, injectionRefs);
+
+        List<ItemProcessListenerProxy> retVal = new ArrayList<ItemProcessListenerProxy>();
+
+        for (ListenerInfo li : stepListenerInfo) {
+            if (li.isItemProcessListener()) {
+                ItemProcessListenerProxy proxy = new ItemProcessListenerProxy((ItemProcessListener) li.getArtifact());
+                proxy.setStepContext(stepContext);
+                retVal.add(proxy);
+            }
+        }
+
+        return retVal;
+    }
+
+    public List<ItemReadListenerProxy> getItemReadListeners(Step step, InjectionReferences injectionRefs, StepContextImpl stepContext) {
+
+        List<ListenerInfo> stepListenerInfo = getStepListenerInfo(step, injectionRefs);
+
+        List<ItemReadListenerProxy> retVal = new ArrayList<ItemReadListenerProxy>();
+
+        for (ListenerInfo li : stepListenerInfo) {
+            if (li.isItemReadListener()) {
+                ItemReadListenerProxy proxy = new ItemReadListenerProxy((ItemReadListener) li.getArtifact());
+                proxy.setStepContext(stepContext);
+                retVal.add(proxy);
+            }
+        }
+
+        return retVal;
+    }
+
+    public List<ItemWriteListenerProxy> getItemWriteListeners(Step step, InjectionReferences injectionRefs, StepContextImpl stepContext) {
+        List<ListenerInfo> stepListenerInfo = getStepListenerInfo(step, injectionRefs);
+
+        List<ItemWriteListenerProxy> retVal = new ArrayList<ItemWriteListenerProxy>();
+
+        for (ListenerInfo li : stepListenerInfo) {
+            if (li.isItemWriteListener()) {
+                ItemWriteListenerProxy proxy = new ItemWriteListenerProxy((ItemWriteListener) li.getArtifact());
+                proxy.setStepContext(stepContext);
+                retVal.add(proxy);
+            }
+        }
+
+        return retVal;
+    }
+
+    public List<RetryProcessListenerProxy> getRetryProcessListeners(Step step, InjectionReferences injectionRefs, StepContextImpl stepContext) {
+        List<ListenerInfo> stepListenerInfo = getStepListenerInfo(step, injectionRefs);
+
+        List<RetryProcessListenerProxy> retVal = new ArrayList<RetryProcessListenerProxy>();
+
+        for (ListenerInfo li : stepListenerInfo) {
+            if (li.isRetryProcessListener()) {
+                RetryProcessListenerProxy proxy = new RetryProcessListenerProxy((RetryProcessListener) li.getArtifact());
+                proxy.setStepContext(stepContext);
+                retVal.add(proxy);
+            }
+        }
+
+        return retVal;
+    }
+    
+    public List<RetryReadListenerProxy> getRetryReadListeners(Step step, InjectionReferences injectionRefs, StepContextImpl stepContext) {
+        List<ListenerInfo> stepListenerInfo = getStepListenerInfo(step, injectionRefs);
+
+        List<RetryReadListenerProxy> retVal = new ArrayList<RetryReadListenerProxy>();
+
+        for (ListenerInfo li : stepListenerInfo) {
+            if (li.isRetryReadListener()) {
+                RetryReadListenerProxy proxy = new RetryReadListenerProxy((RetryReadListener) li.getArtifact());
+                proxy.setStepContext(stepContext);
+                retVal.add(proxy);
+            }
+        }
+
+        return retVal;
+    }
+    
+    public List<RetryWriteListenerProxy> getRetryWriteListeners(Step step, InjectionReferences injectionRefs, StepContextImpl stepContext) {
+        List<ListenerInfo> stepListenerInfo = getStepListenerInfo(step, injectionRefs);
+
+        List<RetryWriteListenerProxy> retVal = new ArrayList<RetryWriteListenerProxy>();
+
+        for (ListenerInfo li : stepListenerInfo) {
+            if (li.isRetryWriteListener()) {
+                RetryWriteListenerProxy proxy = new RetryWriteListenerProxy((RetryWriteListener) li.getArtifact());
+                proxy.setStepContext(stepContext);
+                retVal.add(proxy);
+            }
+        }
+
+        return retVal;
+    }
+    
+    public List<SkipProcessListenerProxy> getSkipProcessListeners(Step step, InjectionReferences injectionRefs, StepContextImpl stepContext) {
+        List<ListenerInfo> stepListenerInfo = getStepListenerInfo(step, injectionRefs);
+
+        List<SkipProcessListenerProxy> retVal = new ArrayList<SkipProcessListenerProxy>();
+
+        for (ListenerInfo li : stepListenerInfo) {
+            if (li.isSkipProcessListener()) {
+                SkipProcessListenerProxy proxy = new SkipProcessListenerProxy((SkipProcessListener) li.getArtifact());
+                proxy.setStepContext(stepContext);
+                retVal.add(proxy);
+            }
+        }
+
+        return retVal;
+    }
+
+    public List<SkipReadListenerProxy> getSkipReadListeners(Step step, InjectionReferences injectionRefs, StepContextImpl stepContext) {
+        List<ListenerInfo> stepListenerInfo = getStepListenerInfo(step, injectionRefs);
+
+        List<SkipReadListenerProxy> retVal = new ArrayList<SkipReadListenerProxy>();
+
+        for (ListenerInfo li : stepListenerInfo) {
+            if (li.isSkipReadListener()) {
+                SkipReadListenerProxy proxy = new SkipReadListenerProxy((SkipReadListener) li.getArtifact());
+                proxy.setStepContext(stepContext);
+                retVal.add(proxy);
+            }
+        }
+
+        return retVal;
+    }
+    
+    public List<SkipWriteListenerProxy> getSkipWriteListeners(Step step, InjectionReferences injectionRefs, StepContextImpl stepContext) {
+        List<ListenerInfo> stepListenerInfo = getStepListenerInfo(step, injectionRefs);
+
+        List<SkipWriteListenerProxy> retVal = new ArrayList<SkipWriteListenerProxy>();
+
+        for (ListenerInfo li : stepListenerInfo) {
+            if (li.isSkipWriteListener()) {
+                SkipWriteListenerProxy proxy = new SkipWriteListenerProxy((SkipWriteListener) li.getArtifact());
+                proxy.setStepContext(stepContext);
+                retVal.add(proxy);
+            }
+        }
+
+        return retVal;
+    }
+
+    public List<StepListenerProxy> getStepListeners(Step step, InjectionReferences injectionRefs, StepContextImpl stepContext) {
+        List<ListenerInfo> stepListenerInfo = getStepListenerInfo(step, injectionRefs);
+
+        List<StepListenerProxy> retVal = new ArrayList<StepListenerProxy>();
+
+        for (ListenerInfo li : stepListenerInfo) {
+            if (li.isStepListener()) {
+                StepListenerProxy proxy = new StepListenerProxy((StepListener) li.getArtifact());
+                proxy.setStepContext(stepContext);
+                retVal.add(proxy);
+            }
+        }
+
+        return retVal;
+    }
+
+    private class ListenerInfo {
+        Object listenerArtifact = null;
+        Class listenerArtifactClass = null;
+        List<Property> propList = null;
+
+        Object getArtifact() {
+            return listenerArtifact;
+        }
+
+        private ListenerInfo(Object listenerArtifact, List<Property> propList) {
+            this.listenerArtifact = listenerArtifact;
+            this.listenerArtifactClass = listenerArtifact.getClass();
+            this.propList = propList;
+        }
+
+        boolean isJobListener() {
+
+            return JobListener.class.isAssignableFrom(listenerArtifactClass);
+        }
+
+        boolean isStepListener() {
+            return StepListener.class.isAssignableFrom(listenerArtifactClass);
+        }
+
+        boolean isChunkListener() {
+            return ChunkListener.class.isAssignableFrom(listenerArtifactClass);
+        }
+
+        boolean isItemProcessListener() {
+            return ItemProcessListener.class.isAssignableFrom(listenerArtifactClass);
+        }
+
+        boolean isItemReadListener() {
+            return ItemReadListener.class.isAssignableFrom(listenerArtifactClass);
+        }
+
+        boolean isItemWriteListener() {
+            return ItemWriteListener.class.isAssignableFrom(listenerArtifactClass);
+        }
+
+        boolean isRetryReadListener() {
+            return RetryReadListener.class.isAssignableFrom(listenerArtifactClass);
+        }
+        
+        boolean isRetryWriteListener() {
+            return RetryWriteListener.class.isAssignableFrom(listenerArtifactClass);
+        }
+        
+        boolean isRetryProcessListener() {
+            return RetryProcessListener.class.isAssignableFrom(listenerArtifactClass);
+        }
+
+        boolean isSkipProcessListener() {
+            return SkipProcessListener.class.isAssignableFrom(listenerArtifactClass);
+        }
+        
+        boolean isSkipReadListener() {
+            return SkipReadListener.class.isAssignableFrom(listenerArtifactClass);
+        }
+        
+        boolean isSkipWriteListener() {
+            return SkipWriteListener.class.isAssignableFrom(listenerArtifactClass);
+        }
+
+        List<Property> getPropList() {
+            return propList;
+        }
+
+        void setPropList(List<Property> propList) {
+            this.propList = propList;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/f7740962/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/PartitionAnalyzerProxy.java
----------------------------------------------------------------------
diff --git a/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/PartitionAnalyzerProxy.java b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/PartitionAnalyzerProxy.java
new file mode 100755
index 0000000..6e29d5a
--- /dev/null
+++ b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/PartitionAnalyzerProxy.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2012 International Business Machines Corp.
+ * 
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership. Licensed under the Apache License, 
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.ibm.jbatch.container.artifact.proxy;
+
+import java.io.Serializable;
+
+import javax.batch.api.partition.PartitionAnalyzer;
+import javax.batch.runtime.BatchStatus;
+
+import com.ibm.jbatch.container.exception.BatchContainerRuntimeException;
+
+public class PartitionAnalyzerProxy extends AbstractProxy<PartitionAnalyzer> implements PartitionAnalyzer {
+
+    PartitionAnalyzerProxy(PartitionAnalyzer delegate) {
+        super(delegate);
+
+    }
+
+    @Override
+    public synchronized void analyzeCollectorData(Serializable data) {
+        
+        try {
+            this.delegate.analyzeCollectorData(data);
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+    @Override
+    public synchronized void analyzeStatus(BatchStatus batchStatus, String exitStatus) {
+        
+        try {
+            this.delegate.analyzeStatus(batchStatus, exitStatus);
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/f7740962/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/PartitionCollectorProxy.java
----------------------------------------------------------------------
diff --git a/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/PartitionCollectorProxy.java b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/PartitionCollectorProxy.java
new file mode 100755
index 0000000..09b2b5e
--- /dev/null
+++ b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/PartitionCollectorProxy.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2012 International Business Machines Corp.
+ * 
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership. Licensed under the Apache License, 
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package com.ibm.jbatch.container.artifact.proxy;
+
+import java.io.Serializable;
+
+import javax.batch.api.partition.PartitionCollector;
+
+import com.ibm.jbatch.container.exception.BatchContainerRuntimeException;
+
+public class PartitionCollectorProxy extends AbstractProxy<PartitionCollector> implements PartitionCollector {
+
+
+    PartitionCollectorProxy(PartitionCollector delegate) { 
+        super(delegate);
+        
+    }
+
+    @Override
+    public Serializable collectPartitionData() {
+        
+        try {
+            return this.delegate.collectPartitionData();
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/f7740962/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/PartitionMapperProxy.java
----------------------------------------------------------------------
diff --git a/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/PartitionMapperProxy.java b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/PartitionMapperProxy.java
new file mode 100755
index 0000000..10fb852
--- /dev/null
+++ b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/PartitionMapperProxy.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2012 International Business Machines Corp.
+ * 
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership. Licensed under the Apache License, 
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package com.ibm.jbatch.container.artifact.proxy;
+
+import javax.batch.api.partition.PartitionMapper;
+import javax.batch.api.partition.PartitionPlan;
+
+import com.ibm.jbatch.container.exception.BatchContainerRuntimeException;
+
+public class PartitionMapperProxy extends AbstractProxy<PartitionMapper> implements PartitionMapper {
+
+
+    PartitionMapperProxy(PartitionMapper delegate) { 
+        super(delegate);
+
+    }
+
+    @Override
+    public PartitionPlan mapPartitions() {
+        
+        try {
+            return this.delegate.mapPartitions();
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/f7740962/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/PartitionReducerProxy.java
----------------------------------------------------------------------
diff --git a/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/PartitionReducerProxy.java b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/PartitionReducerProxy.java
new file mode 100755
index 0000000..4e59057
--- /dev/null
+++ b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/PartitionReducerProxy.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2012 International Business Machines Corp.
+ * 
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership. Licensed under the Apache License, 
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package com.ibm.jbatch.container.artifact.proxy;
+
+import javax.batch.api.partition.PartitionReducer;
+
+import com.ibm.jbatch.container.exception.BatchContainerRuntimeException;
+
+public class PartitionReducerProxy extends AbstractProxy<PartitionReducer> implements PartitionReducer {
+
+    PartitionReducerProxy(PartitionReducer delegate) { 
+        super(delegate);
+
+    }
+
+    @Override
+    public void afterPartitionedStepCompletion(PartitionStatus status) {
+        
+        try {
+            this.delegate.afterPartitionedStepCompletion(status);
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+    @Override
+    public void beforePartitionedStepCompletion() {
+        
+        try {
+            this.delegate.beforePartitionedStepCompletion();
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+    @Override
+    public void beginPartitionedStep() {
+
+        try {
+            this.delegate.beginPartitionedStep();
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+    @Override
+    public void rollbackPartitionedStep() {
+        
+        try {
+            this.delegate.rollbackPartitionedStep();
+        } catch (Exception e) {
+        	this.stepContext.setException(e);
+            throw new BatchContainerRuntimeException(e);
+        }
+    }
+
+}
+
+

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/f7740962/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ProxyFactory.java
----------------------------------------------------------------------
diff --git a/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ProxyFactory.java b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ProxyFactory.java
new file mode 100755
index 0000000..ba3f0fe
--- /dev/null
+++ b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/ProxyFactory.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2012 International Business Machines Corp.
+ * 
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership. Licensed under the Apache License, 
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package com.ibm.jbatch.container.artifact.proxy;
+
+import javax.batch.api.Batchlet;
+import javax.batch.api.Decider;
+import javax.batch.api.chunk.CheckpointAlgorithm;
+import javax.batch.api.chunk.ItemProcessor;
+import javax.batch.api.chunk.ItemReader;
+import javax.batch.api.chunk.ItemWriter;
+import javax.batch.api.partition.PartitionAnalyzer;
+import javax.batch.api.partition.PartitionCollector;
+import javax.batch.api.partition.PartitionMapper;
+import javax.batch.api.partition.PartitionReducer;
+
+import com.ibm.jbatch.container.context.impl.StepContextImpl;
+import com.ibm.jbatch.container.servicesmanager.ServicesManager;
+import com.ibm.jbatch.container.servicesmanager.ServicesManagerImpl;
+import com.ibm.jbatch.container.validation.ArtifactValidationException;
+import com.ibm.jbatch.spi.services.IBatchArtifactFactory;
+
+/*
+ * Introduce a level of indirection so proxies are not instantiated directly by newing them up.
+ */
+public class ProxyFactory {
+
+    protected static ServicesManager servicesManager = ServicesManagerImpl.getInstance();
+
+    private static ThreadLocal<InjectionReferences> injectionContext = new ThreadLocal<InjectionReferences>();
+    
+    protected static IBatchArtifactFactory batchArtifactFactory = servicesManager.getDelegatingArtifactFactory();
+
+    protected static Object loadArtifact(String id, InjectionReferences injectionReferences) {
+        injectionContext.set(injectionReferences);
+        
+        Object loadedArtifact = null;
+        try {
+            loadedArtifact = batchArtifactFactory.load(id);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        return loadedArtifact;
+    }
+    
+    public static InjectionReferences getInjectionReferences() {
+        return injectionContext.get();
+    }
+    
+    /*
+     * Decider
+     */
+    public static DeciderProxy createDeciderProxy(String id, InjectionReferences injectionRefs) throws ArtifactValidationException {
+        Decider loadedArtifact = (Decider)loadArtifact(id, injectionRefs);
+        DeciderProxy proxy = new DeciderProxy(loadedArtifact);
+
+        return proxy;
+    }
+
+    /*
+     * Batchlet artifact
+     */
+    public static BatchletProxy createBatchletProxy(String id, InjectionReferences injectionRefs, StepContextImpl stepContext) throws ArtifactValidationException {
+        Batchlet loadedArtifact = (Batchlet)loadArtifact(id, injectionRefs);
+        BatchletProxy proxy = new BatchletProxy(loadedArtifact);
+        proxy.setStepContext(stepContext);
+        
+        return proxy;
+    }
+    
+    /*
+     * The four main chunk-related artifacts
+     */    
+    
+    public static CheckpointAlgorithmProxy createCheckpointAlgorithmProxy(String id, InjectionReferences injectionRefs, StepContextImpl stepContext) throws ArtifactValidationException {
+        CheckpointAlgorithm loadedArtifact = (CheckpointAlgorithm)loadArtifact(id, injectionRefs);
+        CheckpointAlgorithmProxy proxy = new CheckpointAlgorithmProxy(loadedArtifact);
+        proxy.setStepContext(stepContext);
+        
+        return proxy;
+    }
+    
+    public static ItemReaderProxy createItemReaderProxy(String id, InjectionReferences injectionRefs, StepContextImpl stepContext) throws ArtifactValidationException {
+        ItemReader loadedArtifact = (ItemReader)loadArtifact(id, injectionRefs);
+        ItemReaderProxy proxy = new ItemReaderProxy(loadedArtifact);
+        proxy.setStepContext(stepContext);
+        
+        return proxy;
+    }
+    
+    public static ItemProcessorProxy createItemProcessorProxy(String id, InjectionReferences injectionRefs, StepContextImpl stepContext) throws ArtifactValidationException {
+        ItemProcessor loadedArtifact = (ItemProcessor)loadArtifact(id, injectionRefs);
+        ItemProcessorProxy proxy = new ItemProcessorProxy(loadedArtifact);
+        proxy.setStepContext(stepContext);
+        
+        return proxy;
+    }
+    
+    public static ItemWriterProxy createItemWriterProxy(String id, InjectionReferences injectionRefs, StepContextImpl stepContext) throws ArtifactValidationException {
+        ItemWriter loadedArtifact = (ItemWriter)loadArtifact(id, injectionRefs);
+        ItemWriterProxy proxy = new ItemWriterProxy(loadedArtifact);
+        proxy.setStepContext(stepContext);
+        
+        return proxy;
+    }
+        
+    /*
+     * The four partition-related artifacts
+     */
+    
+    public static PartitionReducerProxy createPartitionReducerProxy(String id, InjectionReferences injectionRefs, StepContextImpl stepContext) throws ArtifactValidationException {
+        PartitionReducer loadedArtifact = (PartitionReducer)loadArtifact(id, injectionRefs);
+        PartitionReducerProxy proxy = new PartitionReducerProxy(loadedArtifact);
+        proxy.setStepContext(stepContext);
+
+        return proxy;
+    }
+    
+    public static PartitionMapperProxy createPartitionMapperProxy(String id, InjectionReferences injectionRefs, StepContextImpl stepContext) throws ArtifactValidationException {
+        PartitionMapper loadedArtifact = (PartitionMapper)loadArtifact(id, injectionRefs);
+        PartitionMapperProxy proxy = new PartitionMapperProxy(loadedArtifact);
+        proxy.setStepContext(stepContext);
+
+        return proxy;
+    }
+    
+    public static PartitionAnalyzerProxy createPartitionAnalyzerProxy(String id, InjectionReferences injectionRefs, StepContextImpl stepContext) throws ArtifactValidationException {
+        PartitionAnalyzer loadedArtifact = (PartitionAnalyzer)loadArtifact(id, injectionRefs);
+        PartitionAnalyzerProxy proxy = new PartitionAnalyzerProxy(loadedArtifact);
+        proxy.setStepContext(stepContext);
+
+        return proxy;
+    }
+    
+    public static PartitionCollectorProxy createPartitionCollectorProxy(String id, InjectionReferences injectionRefs, StepContextImpl stepContext) throws ArtifactValidationException {
+        PartitionCollector loadedArtifact = (PartitionCollector)loadArtifact(id, injectionRefs);
+        PartitionCollectorProxy proxy = new PartitionCollectorProxy(loadedArtifact);
+        proxy.setStepContext(stepContext);
+
+        return proxy;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/f7740962/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/RetryProcessListenerProxy.java
----------------------------------------------------------------------
diff --git a/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/RetryProcessListenerProxy.java b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/RetryProcessListenerProxy.java
new file mode 100755
index 0000000..0218746
--- /dev/null
+++ b/JSR352.Runtime/src/com/ibm/jbatch/container/artifact/proxy/RetryProcessListenerProxy.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2012 International Business Machines Corp.
+ * 
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership. Licensed under the Apache License, 
+ * Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+package com.ibm.jbatch.container.artifact.proxy;
+
+import javax.batch.api.chunk.listener.RetryProcessListener;
+
+import com.ibm.jbatch.container.exception.BatchContainerRuntimeException;
+
+public class RetryProcessListenerProxy extends AbstractProxy<RetryProcessListener> implements RetryProcessListener{
+
+	RetryProcessListenerProxy(RetryProcessListener delegate) { 
+        super(delegate);
+    }
+
+    @Override
+    public void onRetryProcessException(Object item, Exception ex) {
+        
+    	 try {
+             this.delegate.onRetryProcessException(item, ex);
+         } catch (Exception e) {
+         	this.stepContext.setException(e);
+             throw new BatchContainerRuntimeException(e);
+         }
+    }
+}