diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/FlatFileItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/FlatFileItemWriterTests.java
index 8ec1534a6..7d23c926e 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/FlatFileItemWriterTests.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/FlatFileItemWriterTests.java
@@ -110,13 +110,22 @@ public class FlatFileItemWriterTests {
* because running the tests in a UNIX environment locks the file if it's open for writing.
*/
private String readLine() throws IOException {
+ return readLine("UTF-8");
+ }
+
+ /*
+ * Read a line from the output file, if the reader has not been created, recreate. This method is only necessary
+ * because running the tests in a UNIX environment locks the file if it's open for writing.
+ */
+ private String readLine(String encoding) throws IOException {
if (reader == null) {
- reader = new BufferedReader(new InputStreamReader(new FileInputStream(outputFile), "UTF-8"));
+ reader = new BufferedReader(new InputStreamReader(new FileInputStream(outputFile), encoding));
}
return reader.readLine();
- }
+ }
+
/*
* Properly close the output file reader.
*/
@@ -434,8 +443,18 @@ public class FlatFileItemWriterTests {
@Test
// BATCH-1959
- public void testTransactionalRestartWithMultiByteCharacter() throws Exception {
+ public void testTransactionalRestartWithMultiByteCharacterUTF8() throws Exception {
+ testTransactionalRestartWithMultiByteCharacter("UTF-8");
+ }
+ @Test
+ // BATCH-1959
+ public void testTransactionalRestartWithMultiByteCharacterUTF16BE() throws Exception {
+ testTransactionalRestartWithMultiByteCharacter("UTF-16BE");
+ }
+
+ private void testTransactionalRestartWithMultiByteCharacter(String encoding) throws Exception {
+ writer.setEncoding(encoding);
writer.setFooterCallback(new FlatFileFooterCallback() {
@Override
@@ -492,15 +511,14 @@ public class FlatFileItemWriterTests {
// verify what was written to the file
for (int i = 1; i <= 8; i++) {
- assertEquals("téstLine" + i, readLine());
+ assertEquals("téstLine" + i, readLine(encoding));
}
- assertEquals("footer", readLine());
+ assertEquals("footer", readLine(encoding));
// 3 lines were written to the file after restart
- assertEquals(3, executionContext.getLong(ClassUtils.getShortName(FlatFileItemWriter.class) + ".written"));
-
- }
+ assertEquals(3, executionContext.getLong(ClassUtils.getShortName(FlatFileItemWriter.class) + ".written"));
+ }
@Test
public void testOpenWithNonWritableFile() throws Exception {
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemWriterTests.java
index 5b10370c1..a467fdaf7 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemWriterTests.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemWriterTests.java
@@ -60,13 +60,26 @@ public class StaxEventItemWriterTests {
private JAXBItem jaxbItem = new JAXBItem();
+ // test item for writing to output with multi byte character
+ private Object itemMultiByte = new Object() {
+ @Override
+ public String toString() {
+ return ClassUtils.getShortName(StaxEventItemWriter.class) + "-téstStrïng";
+ }
+ };
+
private List extends Object> items = Collections.singletonList(item);
+ private List extends Object> itemsMultiByte = Collections.singletonList(itemMultiByte);
+
private List extends Object> jaxbItems = Collections.singletonList(jaxbItem);
private static final String TEST_STRING = "<" + ClassUtils.getShortName(StaxEventItemWriter.class)
+ "-testString/>";
+ private static final String TEST_STRING_MULTI_BYTE = "<" + ClassUtils.getShortName(StaxEventItemWriter.class)
+ + "-téstStrïng/>";
+
private static final String NS_TEST_STRING = "";
@@ -185,6 +198,68 @@ public class StaxEventItemWriterTests {
assertTrue(outputFile.contains("" + TEST_STRING + TEST_STRING + ""));
}
+ @Test
+ // BATCH-1959
+ public void testTransactionalRestartWithMultiByteCharacterUTF8() throws Exception {
+ testTransactionalRestartWithMultiByteCharacter("UTF-8");
+ }
+
+ @Test
+ // BATCH-1959
+ public void testTransactionalRestartWithMultiByteCharacterUTF16BE() throws Exception {
+ testTransactionalRestartWithMultiByteCharacter("UTF-16BE");
+ }
+
+ private void testTransactionalRestartWithMultiByteCharacter(String encoding) throws Exception {
+ writer.setEncoding(encoding);
+ writer.open(executionContext);
+
+ PlatformTransactionManager transactionManager = new ResourcelessTransactionManager();
+
+ new TransactionTemplate(transactionManager).execute(new TransactionCallback() {
+ @Override
+ public Object doInTransaction(TransactionStatus status) {
+ try {
+ // write item
+ writer.write(itemsMultiByte);
+ }
+ catch (Exception e) {
+ throw new UnexpectedInputException("Could not write data", e);
+ }
+ // get restart data
+ writer.update(executionContext);
+ return null;
+ }
+ });
+ writer.close();
+
+ // create new writer from saved restart data and continue writing
+ writer = createItemWriter();
+ writer.setEncoding(encoding);
+ writer.open(executionContext);
+ new TransactionTemplate(transactionManager).execute(new TransactionCallback() {
+ @Override
+ public Object doInTransaction(TransactionStatus status) {
+ try {
+ writer.write(itemsMultiByte);
+ }
+ catch (Exception e) {
+ throw new UnexpectedInputException("Could not write data", e);
+ }
+ // get restart data
+ writer.update(executionContext);
+ return null;
+ }
+ });
+ writer.close();
+
+ // check the output is concatenation of 'before restart' and 'after
+ // restart' writes.
+ String outputFile = getOutputFileContent(encoding);
+ assertEquals(2, StringUtils.countOccurrencesOf(outputFile, TEST_STRING_MULTI_BYTE));
+ assertTrue(outputFile.contains("" + TEST_STRING_MULTI_BYTE + TEST_STRING_MULTI_BYTE + ""));
+ }
+
@Test
@SuppressWarnings({"unchecked", "rawtypes"})
public void testTransactionalRestartFailOnFirstWrite() throws Exception {
@@ -692,11 +767,21 @@ public class StaxEventItemWriterTests {
* @return output file content as String
*/
private String getOutputFileContent() throws IOException {
- String value = FileUtils.readFileToString(resource.getFile(), null);
- value = value.replace("", "");
+ return getOutputFileContent("UTF-8");
+ }
+
+
+ /**
+ * @param encoding the encoding
+ * @return output file content as String
+ */
+ private String getOutputFileContent(String encoding) throws IOException {
+ String value = FileUtils.readFileToString(resource.getFile(), encoding);
+ value = value.replace("", "");
return value;
}
+
/**
* @return new instance of fully configured writer
*/
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/transaction/TransactionAwareBufferedWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/transaction/TransactionAwareBufferedWriterTests.java
index dcba51971..d562543e3 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/transaction/TransactionAwareBufferedWriterTests.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/transaction/TransactionAwareBufferedWriterTests.java
@@ -189,7 +189,7 @@ public class TransactionAwareBufferedWriterTests {
@Test
@SuppressWarnings({"unchecked", "rawtypes"})
// BATCH-1959
- public void testBufferSizeInTransactionWithMultiByteCharacter() throws Exception {
+ public void testBufferSizeInTransactionWithMultiByteCharacterUTF8() throws Exception {
ArgumentCaptor bb = ArgumentCaptor.forClass(ByteBuffer.class);
when(fileChannel.write(bb.capture())).thenReturn(5);
@@ -210,6 +210,32 @@ public class TransactionAwareBufferedWriterTests {
assertEquals(0, writer.getBufferSize());
}
+ @Test
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ // BATCH-1959
+ public void testBufferSizeInTransactionWithMultiByteCharacterUTF16BE() throws Exception {
+ writer.setEncoding("UTF-16BE");
+
+ ArgumentCaptor bb = ArgumentCaptor.forClass(ByteBuffer.class);
+ when(fileChannel.write(bb.capture())).thenReturn(6);
+
+ new TransactionTemplate(transactionManager).execute(new TransactionCallback() {
+ @Override
+ public Object doInTransaction(TransactionStatus status) {
+ try {
+ writer.write("fóó");
+ }
+ catch (IOException e) {
+ throw new IllegalStateException("Unexpected IOException", e);
+ }
+ assertEquals(6, writer.getBufferSize());
+ return null;
+ }
+ });
+
+ assertEquals(0, writer.getBufferSize());
+ }
+
@Test
@SuppressWarnings({"unchecked", "rawtypes"})
public void testWriteWithRollback() throws Exception {