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 2014/11/18 08:58:11 UTC

[1/2] incubator-batchee git commit: BATCHEE-55 RI Bug 5806 - JobExecution returned by jobOperator.getJobExecutions(jobInstance) has null parameters. Thanks Scott for the patch.

Repository: incubator-batchee
Updated Branches:
  refs/heads/master 39fd1f237 -> a3d42ddbc


BATCHEE-55 RI Bug 5806 - JobExecution returned by jobOperator.getJobExecutions(jobInstance) has null parameters. Thanks Scott for the patch.


Project: http://git-wip-us.apache.org/repos/asf/incubator-batchee/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-batchee/commit/ab1ef84f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-batchee/tree/ab1ef84f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-batchee/diff/ab1ef84f

Branch: refs/heads/master
Commit: ab1ef84fba7bf98c646b8b683173147ba21b0638
Parents: 39fd1f2
Author: Romain Manni-Bucau <rm...@apache.org>
Authored: Tue Nov 18 08:56:04 2014 +0100
Committer: Romain Manni-Bucau <rm...@apache.org>
Committed: Tue Nov 18 08:56:04 2014 +0100

----------------------------------------------------------------------
 .../services/persistence/JDBCPersistenceManagerService.java       | 3 +++
 .../services/persistence/JPAPersistenceManagerService.java        | 1 +
 2 files changed, 4 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/ab1ef84f/jbatch/src/main/java/org/apache/batchee/container/services/persistence/JDBCPersistenceManagerService.java
----------------------------------------------------------------------
diff --git a/jbatch/src/main/java/org/apache/batchee/container/services/persistence/JDBCPersistenceManagerService.java b/jbatch/src/main/java/org/apache/batchee/container/services/persistence/JDBCPersistenceManagerService.java
index 06adf16..765a60d 100755
--- a/jbatch/src/main/java/org/apache/batchee/container/services/persistence/JDBCPersistenceManagerService.java
+++ b/jbatch/src/main/java/org/apache/batchee/container/services/persistence/JDBCPersistenceManagerService.java
@@ -974,6 +974,8 @@ public class JDBCPersistenceManagerService implements PersistenceManagerService
                 final String batchStatus = rs.getString(dictionary.jobExecutionColumns(1));
                 final String exitStatus = rs.getString(dictionary.jobExecutionColumns(4));
                 final String jobName = rs.getString(dictionary.jobInstanceColumns(3));
+                final byte[] buf = rs.getBytes(dictionary.jobExecutionColumns(5));
+                final Properties params = buf != null ? PropertyHelper.stringToProperties(new String(buf)) : null;
 
                 final JobExecutionImpl jobEx = new JobExecutionImpl(jobExecutionId, jobInstanceId, this);
                 jobEx.setCreateTime(createtime);
@@ -983,6 +985,7 @@ public class JDBCPersistenceManagerService implements PersistenceManagerService
                 jobEx.setBatchStatus(batchStatus);
                 jobEx.setExitStatus(exitStatus);
                 jobEx.setJobName(jobName);
+                jobEx.setJobParameters(params);
 
                 data.add(jobEx);
             }

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/ab1ef84f/jbatch/src/main/java/org/apache/batchee/container/services/persistence/JPAPersistenceManagerService.java
----------------------------------------------------------------------
diff --git a/jbatch/src/main/java/org/apache/batchee/container/services/persistence/JPAPersistenceManagerService.java b/jbatch/src/main/java/org/apache/batchee/container/services/persistence/JPAPersistenceManagerService.java
index a0dcbf3..6e2904e 100644
--- a/jbatch/src/main/java/org/apache/batchee/container/services/persistence/JPAPersistenceManagerService.java
+++ b/jbatch/src/main/java/org/apache/batchee/container/services/persistence/JPAPersistenceManagerService.java
@@ -355,6 +355,7 @@ public class JPAPersistenceManagerService implements PersistenceManagerService {
                 jobEx.setBatchStatus(entity.getBatchStatus().name());
                 jobEx.setExitStatus(entity.getExitStatus());
                 jobEx.setJobName(entity.getInstance().getName());
+                jobEx.setJobParameters(entity.getJobProperties());
 
                 result.add(jobEx);
             }


[2/2] incubator-batchee git commit: few tests I seem to have forgotten to commit, sorry

Posted by rm...@apache.org.
few tests I seem to have forgotten to commit, sorry


Project: http://git-wip-us.apache.org/repos/asf/incubator-batchee/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-batchee/commit/a3d42ddb
Tree: http://git-wip-us.apache.org/repos/asf/incubator-batchee/tree/a3d42ddb
Diff: http://git-wip-us.apache.org/repos/asf/incubator-batchee/diff/a3d42ddb

Branch: refs/heads/master
Commit: a3d42ddbc0b21e164c69007f131522addf0dfeeb
Parents: ab1ef84
Author: Romain Manni-Bucau <rm...@apache.org>
Authored: Tue Nov 18 08:58:03 2014 +0100
Committer: Romain Manni-Bucau <rm...@apache.org>
Committed: Tue Nov 18 08:58:03 2014 +0100

----------------------------------------------------------------------
 .../jsefa/JSefaCsvReaderConverterTest.java      |  77 +++++++
 .../jsefa/JSefaCsvWriterConverterTest.java      |  97 ++++++++
 .../jsefa/JSefaFlrReaderConverterTest.java      |  76 +++++++
 .../jsefa/JSefaFlrWriterConverterTest.java      | 101 +++++++++
 .../batchee/jsefa/bean/RecordWithConverter.java | 145 ++++++++++++
 .../jsefa/converter/CustomDateConverter.java    |  54 +++++
 .../jsefa/converter/RecordEnumConverter.java    |  41 ++++
 .../batch-jobs/jsefa-csv-reader-converter.xml   |  28 +++
 .../batch-jobs/jsefa-csv-writer-converter.xml   |  28 +++
 .../batch-jobs/jsefa-flr-reader-converter.xml   |  28 +++
 .../batch-jobs/jsefa-flr-writer-converter.xml   |  29 +++
 .../PartitionPropertySubstitutionTest.java      | 222 +++++++++++++++++++
 .../batch-jobs/partition-propertyResolver.xml   |  32 +++
 13 files changed, 958 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/a3d42ddb/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaCsvReaderConverterTest.java
----------------------------------------------------------------------
diff --git a/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaCsvReaderConverterTest.java b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaCsvReaderConverterTest.java
new file mode 100644
index 0000000..e8ea7ae
--- /dev/null
+++ b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaCsvReaderConverterTest.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.batchee.jsefa;
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.batch.operations.JobOperator;
+import javax.batch.runtime.BatchRuntime;
+
+import org.apache.batchee.extras.typed.NoStateTypedItemWriter;
+import org.apache.batchee.jsefa.bean.RecordWithConverter;
+import org.apache.batchee.jsefa.util.IOs;
+import org.apache.batchee.util.Batches;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * Tests if converter gets picked up if
+ * specified in Object annotation
+ */
+public class JSefaCsvReaderConverterTest {
+
+    @Test
+    public void testRead() throws Exception {
+        String path = "target/work/JSefaCsvReaderWithConverter.csv";
+
+        IOs.write(path,
+                  "string1;123;1;201007161200\n" +
+                  "string2;345;2;199004041350\n" +
+                  "string3;987654321;1;197905072358");
+
+        Properties props = new Properties();
+        props.setProperty("input", path);
+        props.setProperty("specialRecordDelimiter", ";");
+
+        JobOperator operator = BatchRuntime.getJobOperator();
+        Batches.waitForEnd(operator, operator.start("jsefa-csv-reader-converter", props));
+
+        Set<RecordWithConverter> expectedItems = new HashSet<RecordWithConverter>();
+        expectedItems.add(new RecordWithConverter("string1", 123L, RecordWithConverter.RecordEnum.ONE, new GregorianCalendar(2010, Calendar.JULY, 16, 12, 0).getTime()));
+        expectedItems.add(new RecordWithConverter("string2", 345L, RecordWithConverter.RecordEnum.TWO, new GregorianCalendar(1990, Calendar.APRIL, 4, 13, 50).getTime()));
+        expectedItems.add(new RecordWithConverter("string3", 987654321L, RecordWithConverter.RecordEnum.ONE, new GregorianCalendar(1979, Calendar.MAY, 7, 23, 58).getTime()));
+
+        Assert.assertEquals(Storage.STORAGE.size(), expectedItems.size());
+        Assert.assertTrue(Storage.STORAGE.containsAll(expectedItems));
+    }
+
+
+    public static class Storage extends NoStateTypedItemWriter<RecordWithConverter> {
+        public static final Set<RecordWithConverter> STORAGE = new HashSet<RecordWithConverter>();
+
+
+        @Override
+        protected void doWriteItems(List<RecordWithConverter> items) {
+            STORAGE.addAll(items);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/a3d42ddb/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaCsvWriterConverterTest.java
----------------------------------------------------------------------
diff --git a/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaCsvWriterConverterTest.java b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaCsvWriterConverterTest.java
new file mode 100644
index 0000000..cddff61
--- /dev/null
+++ b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaCsvWriterConverterTest.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.batchee.jsefa;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+import java.util.Random;
+import java.util.Set;
+
+import javax.batch.operations.JobOperator;
+import javax.batch.runtime.BatchRuntime;
+
+import org.apache.batchee.extras.typed.NoStateTypedItemReader;
+import org.apache.batchee.extras.typed.NoStateTypedItemWriter;
+import org.apache.batchee.jsefa.bean.RecordWithConverter;
+import org.apache.batchee.jsefa.util.IOs;
+import org.apache.batchee.util.Batches;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * Tests if converter gets picked up if
+ * specified in Object annotation
+ */
+public class JSefaCsvWriterConverterTest {
+
+    @Test
+    public void testWrite() throws Exception {
+        String path = "target/work/JSefaCsvWriterWithConverter.csv";
+
+        Properties props = new Properties();
+        props.setProperty("output", path);
+        props.setProperty("specialRecordDelimiter", ";");
+
+        JobOperator operator = BatchRuntime.getJobOperator();
+        Batches.waitForEnd(operator, operator.start("jsefa-csv-writer-converter", props));
+
+        Assert.assertEquals(IOs.slurp(path), toCsvString());
+    }
+
+
+    private String toCsvString() {
+        StringBuilder builder = new StringBuilder();
+
+        for (RecordWithConverter record : RecordReader.STORAGE) {
+            builder.append(record.getStringValue()).append(';')
+                   .append(record.getLongValue()).append(';')
+                   .append(record.getEnumValue().getCode()).append(';')
+                   .append(new SimpleDateFormat("yyyyMMddHHmm").format(record.getDateValue())).append('\n');
+        }
+
+        return builder.toString();
+    }
+
+
+    public static class RecordReader extends NoStateTypedItemReader<RecordWithConverter> {
+        public static final List<RecordWithConverter> STORAGE = new LinkedList<RecordWithConverter>();
+
+        private int count;
+
+
+        @Override
+        protected RecordWithConverter doRead() {
+            if (count++ == 5) {
+                return null;
+            }
+
+            RecordWithConverter record = new RecordWithConverter("string" + count,
+                                                                 count * 100000L,
+                                                                 RecordWithConverter.RecordEnum.values()[new Random().nextInt(2)],
+                                                                 new GregorianCalendar(count + 2000, count, count + 5, count + 12, count + 30).getTime());
+
+            STORAGE.add(record);
+
+            return record;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/a3d42ddb/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaFlrReaderConverterTest.java
----------------------------------------------------------------------
diff --git a/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaFlrReaderConverterTest.java b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaFlrReaderConverterTest.java
new file mode 100644
index 0000000..d6907d8
--- /dev/null
+++ b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaFlrReaderConverterTest.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.batchee.jsefa;
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.batch.operations.JobOperator;
+import javax.batch.runtime.BatchRuntime;
+
+import org.apache.batchee.extras.typed.NoStateTypedItemWriter;
+import org.apache.batchee.jsefa.bean.RecordWithConverter;
+import org.apache.batchee.jsefa.util.IOs;
+import org.apache.batchee.util.Batches;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * Tests if converter gets picked up if
+ * specified in Object annotation
+ */
+public class JSefaFlrReaderConverterTest {
+
+    @Test
+    public void testRead() throws Exception {
+        String path = "target/work/JSefaFlrReaderWithConverter.csv";
+
+        IOs.write(path,
+                  "string1   123      1  201007161200\n" +
+                  "string2   345      2  199004041350\n" +
+                  "string3   9876543211  197905072358");
+
+        Properties props = new Properties();
+        props.setProperty("input", path);
+
+        JobOperator operator = BatchRuntime.getJobOperator();
+        Batches.waitForEnd(operator, operator.start("jsefa-flr-reader-converter", props));
+
+        Set<RecordWithConverter> expectedItems = new HashSet<RecordWithConverter>();
+        expectedItems.add(new RecordWithConverter("string1", 123L, RecordWithConverter.RecordEnum.ONE, new GregorianCalendar(2010, Calendar.JULY, 16, 12, 0).getTime()));
+        expectedItems.add(new RecordWithConverter("string2", 345L, RecordWithConverter.RecordEnum.TWO, new GregorianCalendar(1990, Calendar.APRIL, 4, 13, 50).getTime()));
+        expectedItems.add(new RecordWithConverter("string3", 987654321L, RecordWithConverter.RecordEnum.ONE, new GregorianCalendar(1979, Calendar.MAY, 7, 23, 58).getTime()));
+
+        Assert.assertEquals(Storage.STORAGE.size(), expectedItems.size());
+        Assert.assertTrue(Storage.STORAGE.containsAll(expectedItems));
+    }
+
+
+    public static class Storage extends NoStateTypedItemWriter<RecordWithConverter> {
+        public static final Set<RecordWithConverter> STORAGE = new HashSet<RecordWithConverter>();
+
+
+        @Override
+        protected void doWriteItems(List<RecordWithConverter> items) {
+            STORAGE.addAll(items);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/a3d42ddb/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaFlrWriterConverterTest.java
----------------------------------------------------------------------
diff --git a/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaFlrWriterConverterTest.java b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaFlrWriterConverterTest.java
new file mode 100644
index 0000000..722109c
--- /dev/null
+++ b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaFlrWriterConverterTest.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.batchee.jsefa;
+
+import java.text.SimpleDateFormat;
+import java.util.GregorianCalendar;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+import java.util.Random;
+
+import javax.batch.operations.JobOperator;
+import javax.batch.runtime.BatchRuntime;
+
+import org.apache.batchee.extras.typed.NoStateTypedItemReader;
+import org.apache.batchee.jsefa.bean.RecordWithConverter;
+import org.apache.batchee.jsefa.util.IOs;
+import org.apache.batchee.util.Batches;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * Tests if converter gets picked up if
+ * specified in Object annotation
+ */
+public class JSefaFlrWriterConverterTest {
+
+    @Test
+    public void testWrite() throws Exception {
+        String path = "target/work/JSefaFlrWriterWithConverter.txt";
+
+        Properties props = new Properties();
+        props.setProperty("output", path);
+
+        JobOperator operator = BatchRuntime.getJobOperator();
+        Batches.waitForEnd(operator, operator.start("jsefa-flr-writer-converter", props));
+
+        Assert.assertEquals(IOs.slurp(path), toFlrString());
+    }
+
+
+    private String toFlrString() {
+        StringBuilder builder = new StringBuilder();
+
+        for (RecordWithConverter record : RecordReader.STORAGE) {
+            builder.append(rightPad(record.getStringValue(), 10))
+                   .append(rightPad(record.getLongValue().toString(), 9))
+                   .append(rightPad(record.getEnumValue().getCode(), 3))
+                   .append(new SimpleDateFormat("yyyyMMddHHmm").format(record.getDateValue())).append('\n');
+        }
+
+        return builder.toString();
+    }
+
+    private String rightPad(String value, int length) {
+        char[] pad = new char[length - value.length()];
+        for (int i = 0; i < pad.length; i++) {
+            pad[i] = ' ';
+        }
+
+        return value.concat(new String(pad));
+    }
+
+
+    public static class RecordReader extends NoStateTypedItemReader<RecordWithConverter> {
+        public static final List<RecordWithConverter> STORAGE = new LinkedList<RecordWithConverter>();
+
+        private int count;
+
+
+        @Override
+        protected RecordWithConverter doRead() {
+            if (count++ == 5) {
+                return null;
+            }
+
+            RecordWithConverter record = new RecordWithConverter("string" + count,
+                                                                 count * 100000L,
+                                                                 RecordWithConverter.RecordEnum.values()[new Random().nextInt(2)],
+                                                                 new GregorianCalendar(count + 2000, count, count + 5, count + 12, count + 30).getTime());
+
+            STORAGE.add(record);
+
+            return record;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/a3d42ddb/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/bean/RecordWithConverter.java
----------------------------------------------------------------------
diff --git a/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/bean/RecordWithConverter.java b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/bean/RecordWithConverter.java
new file mode 100644
index 0000000..a1fcdec
--- /dev/null
+++ b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/bean/RecordWithConverter.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.batchee.jsefa.bean;
+
+import java.util.Date;
+
+import org.apache.batchee.jsefa.converter.CustomDateConverter;
+import org.apache.batchee.jsefa.converter.RecordEnumConverter;
+import net.sf.jsefa.csv.annotation.CsvDataType;
+import net.sf.jsefa.csv.annotation.CsvField;
+import net.sf.jsefa.flr.annotation.FlrDataType;
+import net.sf.jsefa.flr.annotation.FlrField;
+
+@CsvDataType
+@FlrDataType
+public class RecordWithConverter {
+
+
+    public enum RecordEnum {
+        ONE("1"),
+        TWO("2");
+
+        private String code;
+
+        private RecordEnum(String code) {
+            this.code = code;
+        }
+
+        public String getCode() {
+            return code;
+        }
+
+
+        public static RecordEnum getByCode(String code) {
+            for (RecordEnum recordEnum : values()) {
+                if (recordEnum.code.equals(code)) {
+                    return recordEnum;
+                }
+            }
+
+            return null;
+        }
+    }
+
+
+    @CsvField(pos = 1)
+    @FlrField(pos = 1, length = 10)
+    private String stringValue;
+
+    @CsvField(pos = 2)
+    @FlrField(pos = 2, length = 9)
+    private Long longValue;
+
+    @CsvField(pos = 3, converterType = RecordEnumConverter.class)
+    @FlrField(pos = 3, length = 3, converterType = RecordEnumConverter.class)
+    private RecordEnum enumValue;
+
+    @CsvField(pos = 4, converterType = CustomDateConverter.class)
+    @FlrField(pos = 4, length = 12, converterType = CustomDateConverter.class)
+    private Date dateValue;
+
+
+    public RecordWithConverter() {
+        // no-op
+    }
+
+    public RecordWithConverter(String stringValue, Long longValue, RecordEnum enumValue, Date dateValue) {
+        this.stringValue = stringValue;
+        this.longValue = longValue;
+        this.enumValue = enumValue;
+        this.dateValue = dateValue;
+    }
+
+
+    public String getStringValue() {
+        return stringValue;
+    }
+
+    public void setStringValue(String stringValue) {
+        this.stringValue = stringValue;
+    }
+
+    public Long getLongValue() {
+        return longValue;
+    }
+
+    public void setLongValue(Long longValue) {
+        this.longValue = longValue;
+    }
+
+    public RecordEnum getEnumValue() {
+        return enumValue;
+    }
+
+    public void setEnumValue(RecordEnum enumValue) {
+        this.enumValue = enumValue;
+    }
+
+    public Date getDateValue() {
+        return dateValue;
+    }
+
+    public void setDateValue(Date dateValue) {
+        this.dateValue = dateValue;
+    }
+
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) { return true; }
+        if (o == null || getClass() != o.getClass()) { return false; }
+
+        RecordWithConverter that = (RecordWithConverter) o;
+
+        if (dateValue != null ? !dateValue.equals(that.dateValue) : that.dateValue != null) { return false; }
+        if (enumValue != that.enumValue) { return false; }
+        if (longValue != null ? !longValue.equals(that.longValue) : that.longValue != null) { return false; }
+        if (stringValue != null ? !stringValue.equals(that.stringValue) : that.stringValue != null) { return false; }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = stringValue != null ? stringValue.hashCode() : 0;
+        result = 31 * result + (longValue != null ? longValue.hashCode() : 0);
+        result = 31 * result + (enumValue != null ? enumValue.hashCode() : 0);
+        result = 31 * result + (dateValue != null ? dateValue.hashCode() : 0);
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/a3d42ddb/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/converter/CustomDateConverter.java
----------------------------------------------------------------------
diff --git a/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/converter/CustomDateConverter.java b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/converter/CustomDateConverter.java
new file mode 100644
index 0000000..3b0de64
--- /dev/null
+++ b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/converter/CustomDateConverter.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.batchee.jsefa.converter;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import net.sf.jsefa.common.converter.SimpleTypeConverter;
+
+
+public class CustomDateConverter implements SimpleTypeConverter {
+
+    @Override
+    public String toString(Object o) {
+        if (o == null || !(o instanceof Date)) {
+            return null;
+        }
+
+        return getFormat().format((Date) o);
+    }
+
+    @Override
+    public Date fromString(String s) {
+        if (s == null || s.isEmpty()) {
+            return null;
+        }
+
+        try {
+            return getFormat().parse(s);
+        } catch (ParseException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+
+    private SimpleDateFormat getFormat() {
+        return new SimpleDateFormat("yyyyMMddHHmm");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/a3d42ddb/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/converter/RecordEnumConverter.java
----------------------------------------------------------------------
diff --git a/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/converter/RecordEnumConverter.java b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/converter/RecordEnumConverter.java
new file mode 100644
index 0000000..6dfd830
--- /dev/null
+++ b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/converter/RecordEnumConverter.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.batchee.jsefa.converter;
+
+import org.apache.batchee.jsefa.bean.RecordWithConverter;
+import net.sf.jsefa.common.converter.SimpleTypeConverter;
+
+public class RecordEnumConverter implements SimpleTypeConverter {
+
+    @Override
+    public String toString(Object o) {
+        if (o == null || !(o instanceof RecordWithConverter.RecordEnum)) {
+            return null;
+        }
+
+        return ((RecordWithConverter.RecordEnum) o).getCode();
+    }
+
+    @Override
+    public RecordWithConverter.RecordEnum fromString(String s) {
+        if (s == null || s.isEmpty()) {
+            return null;
+        }
+
+        return RecordWithConverter.RecordEnum.getByCode(s.trim());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/a3d42ddb/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-reader-converter.xml
----------------------------------------------------------------------
diff --git a/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-reader-converter.xml b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-reader-converter.xml
new file mode 100644
index 0000000..2bad44c
--- /dev/null
+++ b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-reader-converter.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<job id="jsefa-csv-reader" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
+    <step id="step1">
+        <chunk>
+            <reader ref="jsefaCsvReader">
+                <properties>
+                    <property name="file" value="#{jobParameters['input']}"/>
+                    <property name="objectTypes" value="org.apache.batchee.jsefa.bean.RecordWithConverter"/>
+                </properties>
+            </reader>
+            <writer ref="org.apache.batchee.jsefa.JSefaCsvReaderConverterTest$Storage" />
+        </chunk>
+    </step>
+</job>

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/a3d42ddb/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-converter.xml
----------------------------------------------------------------------
diff --git a/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-converter.xml b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-converter.xml
new file mode 100644
index 0000000..6d8cf3d
--- /dev/null
+++ b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-converter.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<job id="jsefa-csv-reader" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
+    <step id="step1">
+        <chunk>
+            <reader ref="org.apache.batchee.jsefa.JSefaCsvWriterConverterTest$RecordReader" />
+            <writer ref="jsefaCsvWriter">
+                <properties>
+                    <property name="file" value="#{jobParameters['output']}"/>
+                    <property name="objectTypes" value="org.apache.batchee.jsefa.bean.RecordWithConverter"/>
+                </properties>
+            </writer>
+        </chunk>
+    </step>
+</job>

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/a3d42ddb/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-flr-reader-converter.xml
----------------------------------------------------------------------
diff --git a/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-flr-reader-converter.xml b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-flr-reader-converter.xml
new file mode 100644
index 0000000..5136fb0
--- /dev/null
+++ b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-flr-reader-converter.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<job id="jsefa-csv-reader" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
+    <step id="step1">
+        <chunk>
+            <reader ref="jsefaFlrReader">
+                <properties>
+                    <property name="file" value="#{jobParameters['input']}"/>
+                    <property name="objectTypes" value="org.apache.batchee.jsefa.bean.RecordWithConverter"/>
+                </properties>
+            </reader>
+            <writer ref="org.apache.batchee.jsefa.JSefaFlrReaderConverterTest$Storage" />
+        </chunk>
+    </step>
+</job>

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/a3d42ddb/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-flr-writer-converter.xml
----------------------------------------------------------------------
diff --git a/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-flr-writer-converter.xml b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-flr-writer-converter.xml
new file mode 100644
index 0000000..e2e7c28
--- /dev/null
+++ b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-flr-writer-converter.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<job id="jsefa-csv-reader" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
+    <step id="step1">
+        <chunk>
+            <reader ref="org.apache.batchee.jsefa.JSefaFlrWriterConverterTest$RecordReader">
+            </reader>
+            <writer ref="jsefaFlrWriter">
+                <properties>
+                    <property name="file" value="#{jobParameters['output']}"/>
+                    <property name="objectTypes" value="org.apache.batchee.jsefa.bean.RecordWithConverter"/>
+                </properties>
+            </writer>
+        </chunk>
+    </step>
+</job>

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/a3d42ddb/jbatch/src/test/java/org/apache/batchee/test/substitution/PartitionPropertySubstitutionTest.java
----------------------------------------------------------------------
diff --git a/jbatch/src/test/java/org/apache/batchee/test/substitution/PartitionPropertySubstitutionTest.java b/jbatch/src/test/java/org/apache/batchee/test/substitution/PartitionPropertySubstitutionTest.java
new file mode 100644
index 0000000..f0b1adc
--- /dev/null
+++ b/jbatch/src/test/java/org/apache/batchee/test/substitution/PartitionPropertySubstitutionTest.java
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.batchee.test.substitution;
+
+import org.apache.batchee.container.services.persistence.jpa.domain.PropertyHelper;
+import org.apache.batchee.util.Batches;
+import org.testng.annotations.Test;
+
+import javax.batch.api.AbstractBatchlet;
+import javax.batch.api.BatchProperty;
+import javax.batch.api.chunk.AbstractItemReader;
+import javax.batch.api.chunk.AbstractItemWriter;
+import javax.batch.api.partition.AbstractPartitionAnalyzer;
+import javax.batch.api.partition.PartitionCollector;
+import javax.batch.api.partition.PartitionMapper;
+import javax.batch.api.partition.PartitionPlan;
+import javax.batch.api.partition.PartitionPlanImpl;
+import javax.batch.operations.JobOperator;
+import javax.batch.runtime.BatchRuntime;
+import javax.batch.runtime.BatchStatus;
+import javax.batch.runtime.Metric;
+import javax.batch.runtime.StepExecution;
+import javax.batch.runtime.context.JobContext;
+import javax.batch.runtime.context.StepContext;
+import javax.inject.Inject;
+
+import java.io.FileNotFoundException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import static org.testng.Assert.assertEquals;
+
+public class PartitionPropertySubstitutionTest {
+
+    public final static String STEP_PROP = "stepProp";
+    public final static String STEP_PROP_VAL = "stepPropVal";
+    public final static String STEP_CONTEXT_PROPERTY = "STEP_CONTEXT_PROPERTY";
+    public final static String SUBSTITUTION_PROPERTY = "SUBSTITUTION_PROPERTY";
+    
+	@Test
+	public void testPartitionPropertyResolverForCollector() throws Exception {
+        final JobOperator op = BatchRuntime.getJobOperator();
+        Properties jobParams = new Properties();
+        jobParams.setProperty(STEP_PROP, STEP_PROP_VAL);
+		final long id = op.start("partition-propertyResolver", jobParams);
+        Batches.waitForEnd(op, id);
+
+        StepExecution stepExecution = op.getStepExecutions(id).iterator().next();
+
+		assertEquals(op.getJobExecution(id).getBatchStatus(), BatchStatus.COMPLETED);
+
+		ArrayList<String> data = (ArrayList<String>)stepExecution.getPersistentUserData();
+
+		for (String nextStringifiedProps : data) {
+			Properties props = PropertyHelper.stringToProperties(nextStringifiedProps);
+			String valFromStepProp = props.getProperty(STEP_CONTEXT_PROPERTY);
+			String valFromSubstitution = props.getProperty(SUBSTITUTION_PROPERTY);
+			assertEquals(valFromStepProp, STEP_PROP_VAL, "Compare values from step-level property with param used in substitution");
+			assertEquals(valFromSubstitution, STEP_PROP_VAL, "Compare values from step-level property with a collector-property using this step-level property via a 'jobProperties' substitution.");
+		}
+	}
+	
+	@Test
+	public void testPartitionPropertyResolverForMapper() throws Exception {
+        final JobOperator op = BatchRuntime.getJobOperator();
+        Properties jobParams = new Properties();
+        jobParams.setProperty(STEP_PROP, STEP_PROP_VAL);
+		final long id = op.start("partition-propertyResolver", jobParams);
+        Batches.waitForEnd(op, id);
+
+		assertEquals(op.getJobExecution(id).getBatchStatus(), BatchStatus.COMPLETED);
+
+		String exitStatus = op.getJobExecution(id).getExitStatus();
+
+		Properties props = PropertyHelper.stringToProperties(exitStatus);
+
+		String valFromStepProp = props.getProperty(STEP_CONTEXT_PROPERTY);
+		String valFromSubstitution = props.getProperty(SUBSTITUTION_PROPERTY);
+		assertEquals(valFromStepProp, STEP_PROP_VAL, "Compare values from step-level property with param used in substitution");
+		assertEquals(valFromSubstitution, STEP_PROP_VAL, "Compare values from step-level property with a collector-property using this step-level property via a 'jobProperties' substitution.");
+	}
+	
+	/*
+	@Test
+	public void testMapperPropertyResolver() throws Exception {
+		long execId = jobOp.start("partitionPropertyResolverMapperTest", null);
+		Thread.sleep(sleepTime);
+		JobExecution je = jobOp.getJobExecution(execId);
+		
+		assertEquals("batch status", BatchStatus.COMPLETED, je.getBatchStatus());
+		
+		List<StepExecution> stepExec = jobOp.getStepExecutions(execId);
+		String stepProp2Data = stepExec.get(0).getExitStatus();
+		String partitionAndStepPropData = String.valueOf(stepExec.get(0).getPersistentUserData());
+		
+		String[] prop2Tokens = stepProp2Data.split(":");
+		String stepProp2Value = prop2Tokens[1];
+		int partitionsTotal = Integer.parseInt(prop2Tokens[2]);
+		
+		String[] tokens = partitionAndStepPropData.split("#");
+		String[] partitionStepPropValues = new String[tokens.length - 1];
+		
+		for(int i=1; i < tokens.length; i++) {
+			partitionStepPropValues[i - 1] = tokens[i];
+		}
+		
+		int count = 0;
+		for(String s : partitionStepPropValues) {
+			String stepPropsValue = s.substring(s.indexOf("?") + 1);
+			assertEquals("StepProp2's Value ", stepProp2Value, stepPropsValue);
+
+			String partitionStringsValue = s.substring(0, s.indexOf("?"));
+			assertEquals("PartitionString's Value ", partitionStringsValue, stepPropsValue);
+			count++;
+		}
+
+		assertEquals("Paritions seen ", count, partitionsTotal);
+	}
+	*/
+	
+    public static class Analyzer extends AbstractPartitionAnalyzer {
+
+    	@Inject
+    	StepContext stepCtx;
+    	
+    	@Override
+    	public void analyzeCollectorData(Serializable data) throws Exception {
+    		ArrayList<String> currentData = (ArrayList<String>)stepCtx.getPersistentUserData();
+    		if (currentData == null) {
+    			currentData = new ArrayList<String>();
+    		}
+    		currentData.add((String)data);
+
+    		// Set in persistent user data for later test validation
+    		stepCtx.setPersistentUserData(currentData);
+    	}
+    }
+
+    public static class Batchlet extends AbstractBatchlet{
+    	@Override
+    	public String process() throws Exception {	
+    		return "GOOD";
+    	}
+    }
+    
+    public static class Collector implements PartitionCollector {
+
+    	@Inject
+    	StepContext stepCtx;
+    	
+    	@Inject @BatchProperty
+    	String substitutedWithStepPropValue;
+    	
+    	@Override
+    	public String collectPartitionData() throws Exception {
+    		Properties props = new Properties();
+    		String stepCtxPropVal = stepCtx.getProperties().getProperty(STEP_PROP);
+    		props.setProperty(STEP_CONTEXT_PROPERTY, stepCtxPropVal);
+    		props.setProperty(SUBSTITUTION_PROPERTY, substitutedWithStepPropValue);
+    		return PropertyHelper.propertiesToString(props);
+    	}
+    }
+    
+    public static class Mapper implements PartitionMapper{
+    	
+    	@Inject
+    	JobContext jobCtx;
+    	
+    	@Inject
+    	StepContext stepCtx;
+    	
+    	@Inject @BatchProperty
+    	String substitutedWithStepPropValue;
+
+    	@Override
+    	public PartitionPlan mapPartitions() throws Exception {
+
+    		PartitionPlanImpl pp = new PartitionPlanImpl();
+    		pp.setPartitions(3);
+    		Properties p0 = new Properties();
+    		Properties p1 = new Properties();
+    		Properties p2 = new Properties();
+    		Properties[] partitionProps = new Properties[3];
+    		partitionProps[0] = p0;
+    		partitionProps[1] = p1;
+    		partitionProps[2] = p2;
+    		pp.setPartitionProperties(partitionProps);
+    		
+    		Properties props = new Properties();
+    		String stepCtxPropVal = stepCtx.getProperties().getProperty(STEP_PROP);
+    		System.out.println("SKSK: in mapper, stepCtxPropVal = " + stepCtxPropVal);
+    		System.out.println("SKSK: in mapper, substitutedWithStepPropValue = " + substitutedWithStepPropValue);
+    		props.setProperty(STEP_CONTEXT_PROPERTY, stepCtxPropVal);
+    		props.setProperty(SUBSTITUTION_PROPERTY, substitutedWithStepPropValue);
+    		
+    		// Set in exit status for later test validation
+    		jobCtx.setExitStatus(PropertyHelper.propertiesToString(props));
+
+    		return pp;
+    	}
+
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/a3d42ddb/jbatch/src/test/resources/META-INF/batch-jobs/partition-propertyResolver.xml
----------------------------------------------------------------------
diff --git a/jbatch/src/test/resources/META-INF/batch-jobs/partition-propertyResolver.xml b/jbatch/src/test/resources/META-INF/batch-jobs/partition-propertyResolver.xml
new file mode 100644
index 0000000..0620d46
--- /dev/null
+++ b/jbatch/src/test/resources/META-INF/batch-jobs/partition-propertyResolver.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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. -->
+<job id="partition-id" version="1.0" xmlns="http://xmlns.jcp.org/xml/ns/javaee">
+
+	<step id="step1">
+		<properties>
+			<property name="stepProp" value="#{jobParameters['stepProp']}" />
+		</properties>
+
+		<batchlet ref="org.apache.batchee.test.substitution.PartitionPropertySubstitutionTest$Batchlet" />
+		<partition>
+			<mapper ref="org.apache.batchee.test.substitution.PartitionPropertySubstitutionTest$Mapper">
+				<properties>
+					<property name="substitutedWithStepPropValue" value="#{jobProperties['stepProp']}" />
+				</properties>
+			</mapper>
+			<collector ref="org.apache.batchee.test.substitution.PartitionPropertySubstitutionTest$Collector">
+				<properties>
+					<property name="substitutedWithStepPropValue" value="#{jobProperties['stepProp']}" />
+				</properties>
+			</collector>
+			<analyzer ref="org.apache.batchee.test.substitution.PartitionPropertySubstitutionTest$Analyzer"/>
+		</partition>
+	</step>
+</job>