是否可以提取 JDK 系统模块并将其用作独立应用程序 module/JAR 文件?

Is it possible to extract JDK system module and use it as a standalone application module/JAR file?

问题

我在 运行 我的应用程序中使用 AdoptOpenJDK 的 JRE 11*。此应用程序使用 JavaFX,它需要 JDK 的名为 jdk.unsupported.desktop 的系统模块。该模块不存在于提到的 JRE 中。我想知道是否可以从 SDK 中提取这个单一模块并将其包含在非模块化应用程序中

*Adopt 不仅发布了 JDKs,还发布了 JREs

我试过的

我已经使用 jlink 构建了自定义 JRE,包括缺少的模块,它解决了我的问题。但是,我仍然想使用预构建的 Adopt JRE 而不是我需要自己创建的自定义 JRE。

问题

是否可以从 JDK“提取”一个模块并将其作为应用程序模块或常规“第 3 方”jar 在非模块化应用程序中使用?

我不知道有任何 "official" 方法可以将平台模块转换为独立的 JAR。但我相信你可以解压文件 jdk-11/jmods/jdk.unsupported.desktop.jmod 并将其重新打包成 JAR 文件。

  • 复制jdk-11/jmods/jdk.unsupported.desktop.jmod到临时文件jdk.unsupported.desktop.zip
  • 解压jdk.unsupported.desktop.zip
  • jdk.unsupported.desktop/classes目录下的类压缩到jdk.unsupported.desktop.jar

现在,如果您将 jdk.unsupported.desktop.jar 放入类路径,它应该可以与 JRE 11 一起使用。

我还有关于 java.desktop 模块的其他问题 - 如果我想深入了解模块系统,并且出于教育目的,我将尝试仅针对 extract/separate“javax.sound”部分java.desktop 模块来创建我自己的 javax.sound 模块以在不需要整个 java.desktop 模块的 javafx 应用程序中使用 - 怎么做?我首先尝试重新编译 module-info.java 并在那里进行了预期的更改,但我还没有成功......是的,我知道这是唯一的学术辩论,因为我可能无法在任何地方重新分发它,对吗?

modified module-info.java(由 javap 反编译)是这样的:(不知道导入,我添加了它们并留在那里也比现在需要的更多,但我的 javac 命令行仍然抱怨.. .

import javax.sound.midi.*;
import javax.sound.midi.spi.*;
import javax.sound.sampled.*;
import javax.sound.sampled.spi.*;
import com.sun.media.sound.*;


module javax.sound {
  requires java.base;
  requires java.prefs;
  requires transitive java.datatransfer;
  requires transitive java.xml;

  exports javax.sound.midi;
  exports javax.sound.midi.spi;
  exports javax.sound.sampled;
  exports javax.sound.sampled.spi;

  uses javax.sound.midi.spi.MidiDeviceProvider;
  uses javax.sound.midi.spi.MidiFileReader;
  uses javax.sound.midi.spi.MidiFileWriter;
  uses javax.sound.midi.spi.SoundbankReader;
  uses javax.sound.sampled.spi.AudioFileReader;
  uses javax.sound.sampled.spi.AudioFileWriter;
  uses javax.sound.sampled.spi.FormatConversionProvider;
  uses javax.sound.sampled.spi.MixerProvider;

  provides  javax.sound.midi.spi.MidiDeviceProvider with
    com.sun.media.sound.MidiInDeviceProvider,
    com.sun.media.sound.MidiOutDeviceProvider,
    com.sun.media.sound.RealTimeSequencerProvider,
    com.sun.media.sound.SoftProvider;
  provides  javax.sound.midi.spi.MidiFileReader with
    com.sun.media.sound.StandardMidiFileReader;
  provides  javax.sound.midi.spi.MidiFileWriter with
    com.sun.media.sound.StandardMidiFileWriter;
  provides  javax.sound.midi.spi.SoundbankReader with
    com.sun.media.sound.AudioFileSoundbankReader,
    com.sun.media.sound.DLSSoundbankReader,
    com.sun.media.sound.JARSoundbankReader,
    com.sun.media.sound.SF2SoundbankReader;
  provides  javax.sound.sampled.spi.AudioFileReader with
    com.sun.media.sound.AiffFileReader,
    com.sun.media.sound.AuFileReader,
    com.sun.media.sound.SoftMidiAudioFileReader,
    com.sun.media.sound.WaveFileReader,
    com.sun.media.sound.WaveFloatFileReader,
    com.sun.media.sound.WaveExtensibleFileReader;
  provides  javax.sound.sampled.spi.AudioFileWriter with
    com.sun.media.sound.AiffFileWriter,
    com.sun.media.sound.AuFileWriter,
    com.sun.media.sound.WaveFileWriter,
    com.sun.media.sound.WaveFloatFileWriter;
  provides  javax.sound.sampled.spi.FormatConversionProvider with
    com.sun.media.sound.AlawCodec,
    com.sun.media.sound.AudioFloatFormatConverter,
    com.sun.media.sound.PCMtoPCMCodec,
    com.sun.media.sound.UlawCodec;
  provides  javax.sound.sampled.spi.MixerProvider with
    com.sun.media.sound.DirectAudioDeviceProvider,
    com.sun.media.sound.PortMixerProvider;
}

这还不行:javac -p %JAVA_HOME\jmod% module-info.java

module-info.java:1: error: package javax.sound.midi is not visible
import javax.sound.midi.*;
                  ^
  (package javax.sound.midi is declared in the unnamed module, but module javax.sound does not read it)
module-info.java:2: error: package javax.sound.midi.spi is not visible
import javax.sound.midi.spi.*;
                       ^
  (package javax.sound.midi.spi is declared in the unnamed module, but module javax.sound does not read it)
module-info.java:3: error: package javax.sound.sampled is not visible
import javax.sound.sampled.*;
                  ^
  (package javax.sound.sampled is declared in the unnamed module, but module javax.sound does not read it)
module-info.java:4: error: package javax.sound.sampled.spi is not visible
import javax.sound.sampled.spi.*;