コードベースをJava 11にアップグレードしようとしています。残念ながら、私のコードはSun.misc.BASE64Encoder
およびDecoder
を内部で使用するサードパーティライブラリに依存しています。 Sun.misc
パッケージがJava 11 JREから削除されているため、失敗しています。そのライブラリの所有者はまだその依存関係を置き換えていないため、ながら。
コードを制御できる場合は、Java.util.BASE64クラスを使用しますが、前述のとおり、これらは別のライブラリからの推移的な依存関係として発生しているため、変更できません。
私は賢く、それらのクラスだけで新しいjarを作成すると思いましたが、何らかの理由でそのjarは無視されています。
<dependency>
<groupId>Sun.misc</groupId>
<artifactId>BASE64</artifactId>
<version>1.8</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/Sun.jar</systemPath>
</dependency>
また、明示的にクラスパスに追加しようとしましたが、まだうまくいきませんでした
これは、JREが操作を妨げているパッケージの1つですか、それとも一部のモジュール仕様がないのですか、それともショーストッパーですか?
これが出力です
Java.lang.NoClassDefFoundError: Sun/misc/BASE64Encoder
at com.propsco.util.support.PropsLoader.save(PropsLoader.Java:478) ~[props-client-2.2.1.jar:na]
この回答は、
> Java --version
openjdk 11.0.3 2019-04-16
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.3+7)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.3+7, mixed mode)
最初に、BASE64Encoder
をオーバーライドするプロジェクトを作成します。それをSun-misc-override
と呼びましょう。 src\main\Java
の下に、Sun.misc
クラスを含むBASE64Encoder
パッケージを作成します。
package Sun.misc;
public class BASE64Encoder {
public String encode(byte[] aBuffer) {
return "Fake it until you make it!";
}
}
コンパイルしようとすると、Sun\misc\BASE64Encoder.Java:1: error: package exists in another module: jdk.unsupported
エラーが発生します。
これにより、 パッチモジュールjdk.unsupported
に必要なヒントが得られます。これは、元のSun.misc
パッケージのクラスが、モジュールシステムがJava 9でロールアウトされた後、時間の経過とともに削除されたときにjdk.unsupported
モジュールに移動されたためです(参照 JEP-260 )。
Mavenでは、コンパイラプラグインを次のように設定できます。
<plugin>
<groupId>org.Apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>11</release>
<compilerArgs>
<arg>--patch-module</arg>
<arg>jdk.unsupported=${project.basedir}/src/main/Java</arg>
</compilerArgs>
</configuration>
</plugin>
com.example:Sun-misc-override:1.0.0-SNAPSHOT
がビルドされたら、結果のJARを「メイン」プロジェクトに配置します(例と同じように)。 lib
ディレクトリ。私はそれを通常のMaven依存関係で動作させる方法を見つけていません。
次に、「メイン」プロジェクトでコンパイラプラグインを設定します。
<plugin>
<groupId>org.Apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>11</release>
<compilerArgs>
<arg>--patch-module=jdk.unsupported=${project.basedir}/lib/Sun-misc-override-1.0.0-SNAPSHOT.jar</arg>
</compilerArgs>
</configuration>
</plugin>
(おそらく MCOMPILER-311 が原因で、使用しようとしたときにNPEを取得していました
<compilerArgs>
<arg>--patch-module</arg>
<arg>jdk.unsupported=${project.basedir}/lib/Sun-misc-override-1.0.0-SNAPSHOT.jar</arg>
</compilerArgs>
バグはmaven-compiler-plugin 3.8.0で修正されることになっていて、Sun-misc-override
のPOMで正常に機能したとしても)
現在、私の「メイン」プロジェクトはj11
と呼ばれ、1つのクラスがあります。
package com.example;
import Sun.misc.BASE64Encoder;
public class BASE64EncoderTest {
public static void main(String[] args) {
System.out.println("Testing - " + new BASE64Encoder().encode(new byte[0]));
}
}
実行するには、--patch-module
を再度指定する必要があります。
> Java --patch-module=jdk.unsupported=lib\Sun-misc-override-1.0.0-SNAPSHOT.jar -cp target\j11-1.0.0-SNAPSHOT.jar com.example.BASE64EncoderTest
Testing - Fake it until you make it!
過去のバージョンでは、Sunは、現在試みている方法でランタイムを改ざんする方法がないことを確認するために多大な努力を払いました(これほど簡単だったのであれば、誰もがランタイムの独自のプライベートバリアントを作成できたでしょう-そして確かにあなたはそれが良いことではなかっただろうと理解するでしょう)。詳細はわかりませんが、「パッケージ名がthisまたはthatなどの場合、ロードはrt.jarからのみ行われます」-クラスローダーのハードコードにハードコードされています。それらの強制措置(または同様の)がまだ有効である可能性が非常に高いようです。
あなたの選択肢が何であるかをよく理解していると思うので、それは問題ではなかったので、私の答えの残りを捨てました。