Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows で使っている Java が Adopt Open JDK だと "AozoraEpub3でEPUBに変換" するときにエラーになる #399

Open
ndxbn opened this issue Jun 6, 2022 · 12 comments

Comments

@ndxbn
Copy link

ndxbn commented Jun 6, 2022

掲題のとおりです。
この ISSUE は、どちらかというと FAQ 的な内容になっているので、適切な場所があるのであれば、そちらに移動し、Close してください。

利用者側がとれる対処方法

Oracle Java へ向いているかどうかは、CLI からの確認はおそらくできません。環境変数 PATH を見て、大丈夫そうかどうかを確認するしかないと思います。

環境変数 PATH が正しく設定できている例

環境変数 PATH が正しく設定できている例

なぜ Oracle Java 以外がインストールされた状態になってしまったのか

私の場合は、Chocolatey で Java に依存しているものをインストールしているのですが、それらが2017年の Oracle Java の有償化に伴って Adopt へ依存先を変更したためでした。
例えば PlantUML などを使っている場合はなりがちだと想います。
これで、パッケージマネージャ上では Oracle Java への依存がなくなった状態となり、クリーンアップをしたことで、Oracle Java がアンインストールされました。

実行時のエラーと narou trace の内容

I:\narou>narou convert 1
ID:1 聖女の魔力は万能です の変換を開始
縦書用の変換が終了しました
AozoraEpub3でEPUBに変換しています...C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/novelconverter.rb:202:in `txt_to_epub': invalid byte sequence in UTF-8 (ArgumentError)
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/novelconverter.rb:315:in `convert_txt_to_ebook_file'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/command/convert.rb:300:in `convert_txt_to_ebook_file'

  エラーが発生したため終了しました。
  詳細なエラーログは narou trace で表示出来ます。もしくは --backtrace オプションを付けて再度実行して下さい。

I:\narou>narou trace
--- 2022/06/11 13:50:12 ---
C:/Ruby30-x64/bin/narou convert 1

C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/novelconverter.rb:202:in `txt_to_epub': invalid byte sequence in UTF-8 (ArgumentError)
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/novelconverter.rb:315:in `convert_txt_to_ebook_file'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/command/convert.rb:300:in `convert_txt_to_ebook_file'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/commandbase.rb:152:in `call'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/commandbase.rb:152:in `hook_call'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/command/convert.rb:252:in `block in convert_novel_main'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/command/convert.rb:248:in `each'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/command/convert.rb:248:in `convert_novel_main'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/command/convert.rb:201:in `block (2 levels) in convert_novels'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/mixin/locker.rb:26:in `lock'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/command/convert.rb:200:in `block in convert_novels'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/command/convert.rb:199:in `each'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/command/convert.rb:199:in `with_index'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/command/convert.rb:199:in `convert_novels'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/command/convert.rb:159:in `block in main'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/command/convert.rb:152:in `each'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/command/convert.rb:152:in `main'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/command/convert.rb:133:in `execute'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/commandbase.rb:125:in `execute!'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/commandbase.rb:134:in `execute!'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/command/convert.rb:123:in `block in execute!'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/narou.rb:369:in `concurrency_call'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/command/convert.rb:122:in `execute!'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/commandline.rb:29:in `run'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/commandline.rb:43:in `run!'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/narou.rb:50:in `block in <top (required)>'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/lib/backtracer.rb:16:in `capture'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/narou.rb:49:in `<top (required)>'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/bin/narou:13:in `require_relative'
  from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/narou-3.8.1/bin/narou:13:in `<top (required)>'
  from C:/Ruby30-x64/bin/narou:25:in `load'
  from C:/Ruby30-x64/bin/narou:25:in `<main>'
@ndxbn
Copy link
Author

ndxbn commented Jun 6, 2022

ref #395 :おそらく同じような内容なんだと思います。インストールし直したのかどうかはわかりませんが、 PATH が書き換わったとかなんじゃないかなぁと思ってます。

@takotakot
Copy link

エラー

参考までに、どのようなエラーとなるのか共有していただくことはできますか?
エラーメッセージで検索する方もいらっしゃりそうです。

@ndxbn
Copy link
Author

ndxbn commented Jun 11, 2022

Eclipse Adoptium の jre-18.0.1.10-hotspot では再現しました。
Adopt Open JDK の最新版である OpenJDK 16 では再現できませんでした。

おそらく 17 か 18 か、もしくは Transition to Eclipse - An Update | AdoptOpenJDK Blog のときに変更になったのだと思います。

@topstone
Copy link
Contributor

topstone commented Jun 14, 2022

私は ScoopOpenJDK を入れて使っています。

OpenJDK 18 では再現しました。OpenJDK 17 では再現しませんでした。

ちゃんと調べていませんが、「Java 18 でデフォルトcharset が UTF-8 に。Windows環境のアプリ等は確認要」という辺りが原因のような気がします。

@topstone
Copy link
Contributor

topstone commented Jun 18, 2022

以下、正しい対処法ではなく「取り敢えず動かす」ための修正です。かなり強引なので、内容が理解できる方のみ参考にして下さい。

lib/novelconverter.rb の168行目を

java_encoding = ""

と変更し、199行目を

stdout_capture = res[0].force_encoding('Windows-31J').encode('UTF-8')

と変更すると、OpenJDK 18, 19, 20 でも error なしに変換できるっぽいです。(ただし、この変更をしても202行目の検出が正常に動作するかどうかはわかりません。)

なお、136行目の -c 0 も AozoraEpub3 側で error になるようで、逆に133行目の -c FILENAME だと大丈夫に見えるので、私は現時点では136行目を以下のように変更して使っています。

cover_option = %!--cover "#{cover_filename}"!

参考までに、現時点の私の環境は以下の通りです。

  • Windows 10 Home 21H1 (64-bit)
  • ConEmu 220418 (64-bit)
  • PowerShell 7.2.4 (64-bit)
  • ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x64-mingw-ucrt]
  • narou.rb 3.8.1
  • AozoraEpub3 1.1.1b13Q
  • OpenJDK 17.0.2, 18.0.1.1, 19-27, 20-2

@kubo
Copy link
Contributor

kubo commented Jun 19, 2022

予想が入っていて、試験もしていませんが、以下のどちらかの方法で直るのではないかと思う。

  1. 以下の行のダブルクォートの中に -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 を追加
    java_encoding = "-Dfile.encoding=UTF-8"

または

  1. 以下の部分で UTF-8 決め打ちにする代わりに、UTF-8 として不正な場合はロケールのエンコーディングを使用

    narou/lib/helper.rb

    Lines 422 to 423 in 1b07ae1

    stdout.force_encoding(Encoding::UTF_8)
    stderr.force_encoding(Encoding::UTF_8)

    例えば、以下のコードを helper.rb に追加して、stdout.force_encoding(Encoding::UTF_8)guess_encoding(stdout) に変更(stderrも同様)
    ENCODING_CANDIDATES = [Encoding::UTF_8, Encoding.find('locale')]
    def guess_encoding(s)
      old_enc = s.encoding
      ENCODING_CANDIDATES.each do |enc|
        s.force_encoding(enc)
        if s.valid_encoding?
          s.encode!(Encoding::UTF_8)
          return
        end
      end
      s.force_encoding(old_enc)
      raise "Cannot guess encoding of #{s}"
    end

理由

-Dfile.encoding=UTF-8 を java の引数に渡しているのは、標準出力の出力先がパイプやファイルのときの文字コードを UTF-8 にするのが目的と思われる。しかし、Java 18 からこの方法は使えなくなった。
https://bugs.openjdk.org/browse/JDK-8283620 には it cannot be officially changed any more. と書かれていて、Java 18 では公式な方法では変更不可能。
そこで、非公式な方法で対処するのが上記の 1番目の案。2番目は UTF-8 でもロケールのエンコーディングでもどちらでも対処できるようにする案。

場合によっては2番目の案はさらに修正が必要かもしれない。上記の案では標準出力全体が同じ文字コードである必要があるが、もしも2つの文字コードが混在とかしていたら、行に分割して、行毎に文字コードを推測するといった処理が必要になるかも。

未確認ですが、Java 19 からなら、-Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8 が使えるかもしれない。 https://download.java.net/java/early_access/loom/docs/api/java.base/java/lang/System.html#stdout.encoding によるとJava起動時には UTF-8 に設定可。ただし、Java 18 のドキュメントには載ってないので、Java 18 での回避策にはならないと思う。

... Windows は使ってないので、上記はすべて机上の推論です ...

@topstone
Copy link
Contributor

この問題について、「取り敢えず動かす」形に変更した gem を narouq という名称で置いておきます

  • 妥当な修正方法なのかどうか分からないので、本家には pull request を投げておりません。
  • 変更内容はご自身で確認下さい。
  • 本家「narou」に対して「narouq」という名称にしたため、本家との併存が可能です。
  • しっかり試したわけではないのですが、私の環境では Java17 でも Java20 でも動きました。

@topstone
Copy link
Contributor

topstone commented Jan 20, 2023

参考になる方もいると思いますので、2023年12月時点の私の環境を記しておきます。

  • Windows 11 Home 23H2 (64-bit)
  • ConEmu 230724 (64-bit)
  • PowerShell 7.4.0 (64-bit)
  • PowerShell 利用時にはいつも [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding('utf-8') を実行
  • ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x64-mingw-ucrt]
  • 改造版 AozoraEpub3 1.1.1b18Q
  • OpenJDK 22 Early-Access Build 22
  • narouq 3.8.2.q3 (なお、本家 narou.rb 3.8.2 では動きませんでした)

@topstone
Copy link
Contributor

ご存知の方も多いと思いますが、最新の改造版 AozoraEpub3 である 1.1.1b15Q は既に Java 8 では動きません

Java 8 の active support 期間は2022年3月31日に終了しているので、改造版 AozoraEpub3 が (最新の LTS である) Java 17 に合わせるのは妥当だと思います。(Java 17 の active support 期間は2026年9月30日まで。) 前述してありますが、Java 21 でも動きます。

@happynow
Copy link
Contributor

happynow commented Jan 3, 2024

kuboさんが書かれた通り、現行の narou.rb 3.8.2 が Java19で新たに追加された実行パラメータ stdout.encodingstdout.encoding に対応していません。

koboさんの 1 の方法が簡単で良いと思います。sunのパラメータは非公式なものですが既存の動作に悪影響はありません。

修正前

java_encoding = "-Dfile.encoding=UTF-8"

下記のように sun. のプレフィックスが付いたもの(非公式)と付いてないもの(公式)を同時に指定してもいいでしょう。
そうすれば、Java18だとか19だとか、バージョンに関係なく動作すると思います。
存在しないパラメータをコマンドオプション -D で指定しても実行エラーにならないはずなので。

修正案 novelconverter.rb  168行目

    java_encoding = "-Dfile.encoding=UTF-8" +
                    " -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8" +
                    " -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8"

この修正を、とりあえず以下の環境で試したらエラーが解消されました。

環境共通
Windows 10 Home(64bit) 22H2
narou-3.8.2

環境1
openjdk 21.0.1 2023-10-17 LTS
AozoraEpub3-1.1.1b19Q
→修正前:エラー、修正後:エラー解消

環境2
java 18 2022-03-22
AozoraEpub3-1.1.0b55Q
→修正前:エラー、修正後:エラー解消

環境3
openjdk 9.0.4
AozoraEpub3-1.1.0b55Q
→修正前後とも正常動作

1 の方法だけで十分かもしれませんが、1 と 2 の両方の対応を実装することも考えられます。

ただし、2 の方法は java.exe の時だけ実行するよう条件付けたほうがいいかもしれません。
問題の Helper::AsyncCommand.exec メソッドは AozoraEpub3 以外でも使っています。
例えば kindlegen.exe の実行でもこのメソッドを使っており、更に呼び出し元で

stdout_capture.force_encoding(Encoding::UTF_8)

と、force_encoding をもう一回やっています。これは削除すればいいと思いますが、注意が必要です。
ENCODING_CANDIDATES に何を設定するかも、もう少し検討が必要でしょう。

なお、いくつかのJDKで試したところ、
sun. が付いていない stdout.encoding, stderr.encoding が追加されたのは jdk19 でしたが
oracle-jdk12、open-jdk9 でも既に sun.stdout.encoding, sun.stderr.encoding のプロパティは非公式ながら機能してました。

@Rich-Richie
Copy link

このAozoraEpub3のエラーは、narouの最新バージョン(v 3.9)で修正されましたか?混乱しています。また、このコンポーネントはどの程度重要なのでしょうか?私はこのアプリを使っていて問題を感じたことはありません。

@kokotaro
Copy link

kokotaro commented Apr 6, 2024

UbuntuでopenJDK21(openjdk-21-jdk)を使用した場合、解消
WindowsでAdoptium(OpenJDK21U-jdk_x64_windows_hotspot_21.0.2_13.msi)を使用した場合、解消
Java8が存在しAozoraEpub3-1.1.0b46.zipを手元に保管している場合に影響は無いですが、既に正式版を公式サイト
からダウンロード出来ない以上、改造版を使用するユーザーが増える傾向を考えるとそこそこ重要度高いと思います。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants