Repository: dita-ot/dita-ot
Issue: DITA-OT 3.6 or above can't handle Input file of non-ASCII path.

## Expected Behavior
<!-- If you're describing a bug, tell us what should happen. -->
Input file of non-ASCII path should be processed properly.

## Actual Behavior
<!-- Tell us what happens instead of the expected behavior. -->
When the full path of input file contains non-ASCII characters, a fatal error occurs.
This behavior depends on DITA-OT version.

- 3.7.2 -> Failed
- 3.6.1 -> Failed
- 3.5.4 -> Success

## Possible Solution
<!-- Optional suggestions on how to fix the issue, or implement the changes. -->
<!-- If you know how to fix the issue, please create a pull request instead. -->
Probably the direct cause of this error is the encoding of .job.xml file created in Temp directory.
The encoding of .job.xml file is Shift-JIS which is the default encoding of Japanese environment.

## Steps to Reproduce
<!-- Test case, Gist, set of files or steps required to reproduce the issue. -->

1. Unzip the following sample to some directory.
2. run dita command `dita.bat -i .\\サンプル\\hierarchy.ditamap -f pdf`

[DITA-OT_non-ASCII_path_sample.zip](https://github.com/dita-ot/dita-ot/files/8849315/DITA-OT_non-ASCII_path_sample.zip)

<!-- Create a Gist via <https://gist.github.com/> to upload your test files. -->
<!-- Link to the Gist from the issue or attach a .zip archive of your files. -->

## Copy of the error message, log file or stack trace
<!-- Long logs should be attached or in linked Gists, not in the issue body. -->
```
C:\\Temp\\DITA-OT_issue> C:\\apl\\dita-ot-3.7.2\\bin\\dita.bat -i .\\サンプル\\hierarchy.ditamap -f pdf
 [pipeline]  Error reported by XML parser: Invalid byte 1 of 1-byte UTF-8 sequence.
 [pipeline] Failed to transform document: Failed to transform document: org.xml.sax.SAXParseException; systemId: file:/C:/Users/lis74h/AppData/Local/Temp/temp20220607095738941/.job.xml; lineNumber: 1; columnNumber: 90; Invalid byte 1 of 1-byte UTF-8 sequence.
[i18n-preprocess] [Fatal Error] stage2.fo:86:159: XML document structures must start and end within the same entity.
Error: The following error occurred while executing this line:
C:\\apl\\dita-ot-3.7.2\\plugins\\org.dita.pdf2\\build.xml:337: java.io.IOException: Failed to read document: XML document structures must start and end within the same entity.
```

.job.xml file in Temp directory: [job_xml.zip](https://github.com/dita-ot/dita-ot/files/8849398/job_xml.zip)

## Environment
<!-- Include relevant details about the environment you experienced this in. -->

* DITA-OT version: 3.7.2
* Operating system and version: Windows 10 21H2
* How did you run DITA-OT? dita command
* Transformation type: PDF

<!--
Before submitting, check the Preview tab above to verify the XML markup appears
correctly and remember you can edit the description later to add information.
-->


Changed files:
src/main/java/org/dita/dost/util/Job.java, src/test/java/org/dita/dost/util/JobTest.java

diff --git a/src/main/java/org/dita/dost/util/Job.java b/src/main/java/org/dita/dost/util/Job.java
index 0b930f263..dc961eb94 100644
--- a/src/main/java/org/dita/dost/util/Job.java
+++ b/src/main/java/org/dita/dost/util/Job.java
@@ -27,6 +27,8 @@ import javax.xml.transform.dom.DOMResult;
 import java.io.*;
 import java.lang.reflect.Field;
 import java.net.URI;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.StandardOpenOption;
 import java.util.*;
@@ -310,7 +312,7 @@ public final class Job {
      * @throws IOException if writing configuration files failed
      */
     public void write() throws IOException {
-        try (Writer outStream = new BufferedWriter(new OutputStreamWriter(getStore().getOutputStream(jobFile.toURI())))) {
+        try (Writer outStream = new BufferedWriter(new OutputStreamWriter(getStore().getOutputStream(jobFile.toURI()), StandardCharsets.UTF_8))) {
             XMLStreamWriter out = null;
             try {
                 out = XMLOutputFactory.newInstance().createXMLStreamWriter(outStream);
diff --git a/src/test/java/org/dita/dost/util/JobTest.java b/src/test/java/org/dita/dost/util/JobTest.java
index 7930e5b6e..1cbda8ebc 100644
--- a/src/test/java/org/dita/dost/util/JobTest.java
+++ b/src/test/java/org/dita/dost/util/JobTest.java
@@ -12,9 +12,13 @@ import static org.dita.dost.util.Constants.*;
 import static org.dita.dost.util.URLUtils.*;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.reflect.Field;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -23,7 +27,7 @@ import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Ignore;
 import org.junit.Test;
-
+import org.apache.commons.io.FileUtils;
 import org.dita.dost.TestUtils;
 
 public final class JobTest {
@@ -91,6 +95,31 @@ public final class JobTest {
         final long end = System.currentTimeMillis();
         System.out.println(((end - start)) + " ms");
     }
+    
+    @Test
+    public void writeUTF8() throws Exception {
+        //Reset default encoding field in order to re-compute it after setting the file.encoding system property.
+        Field defaultCSField = Class.forName("java.nio.charset.Charset").getDeclaredField("defaultCharset");
+        defaultCSField.setAccessible(true);
+        defaultCSField.set(null, null);
+        String initialEncoding = System.getProperty("file.encoding");
+        try {
+            System.getProperties().setProperty("file.encoding", "ASCII");
+            job.add(Job.FileInfo.builder()
+                    .src(new File(tempDir, "\\u633F.dita").toURI())
+                    .uri(new File("\\u633F.dita").toURI())
+                    .result(new File(tempDir, "\\u633F.html").toURI())
+                    .format("dita")
+                    .hasKeyref(true)
+                    .hasLink(true)
+                    .build());
+            job.write();
+            File jobFile = new File(tempDir, ".job.xml");
+            assertTrue(FileUtils.readFileToString(jobFile, StandardCharsets.UTF_8).contains("\\u633F.dita"));
+        } finally {
+            System.getProperties().setProperty("file.encoding", initialEncoding);
+        }
+    }
 
     @AfterClass
     public static void tearDown() throws IOException {