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

Jansi 2.4.1 JPMS configuration regresses JLine #286

Open
cdivilly opened this issue Apr 18, 2024 · 1 comment
Open

Jansi 2.4.1 JPMS configuration regresses JLine #286

cdivilly opened this issue Apr 18, 2024 · 1 comment

Comments

@cdivilly
Copy link

cdivilly commented Apr 18, 2024

In Jansi 2.4.0 this is the JPMS configuration:

          <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.2.0</version>
                <configuration>
                    <archive>
                        <manifestEntries>
                            <Automatic-Module-Name>org.fusesource.jansi</Automatic-Module-Name>
                        </manifestEntries>
                        <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
                    </archive>
                </configuration>
            </plugin>

This makes JAnsi JPMS aware/enabled by giving it an Automatic Module Name. Jars with an automatic module name when loaded on the module path are treated as a JPMS module with the given name, with ALL packages in the jar exported.

This is the JPMS configuration in 2.4.1

            <plugin>
                <groupId>org.moditect</groupId>
                <artifactId>moditect-maven-plugin</artifactId>
                <version>1.0.0.Final</version>
                <executions>
                    <execution>
                        <id>add-module-infos</id>
                        <goals>
                            <goal>add-module-info</goal>
                        </goals>
                        <phase>package</phase>
                        <configuration>
                            <jvmVersion>9</jvmVersion>
                            <module>
                                <moduleInfo>
                                    <name>org.fusesource.jansi</name>
                                    <exports>org.fusesource.jansi;
                                        org.fusesource.jansi.io;</exports>
                                </moduleInfo>
                            </module>
                            <overwriteExistingFiles>true</overwriteExistingFiles>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

This generates a module-info.class instead of adding Automatic-Module-Name to the manifest. In this case only the following packages are exported from the org.fusesource.jansi module:

  • org.fusesource.jansi
  • org.fusesource.jansi.io

No other packages defined in JAnsi are visible to other modules. This regresses using JLine as a JPMS module because it is no longer able to access the package org.fusesource.jansi.internal which is used in the class JansiWinSysTerminal:

package org.jline.terminal.impl.jansi.win;

//...

import org.fusesource.jansi.internal.Kernel32;
import org.fusesource.jansi.internal.Kernel32.CONSOLE_SCREEN_BUFFER_INFO;
import org.fusesource.jansi.internal.Kernel32.INPUT_RECORD;
import org.fusesource.jansi.internal.Kernel32.KEY_EVENT_RECORD;

//...

import static org.fusesource.jansi.internal.Kernel32.GetConsoleScreenBufferInfo;
import static org.fusesource.jansi.internal.Kernel32.GetStdHandle;
import static org.fusesource.jansi.internal.Kernel32.INVALID_HANDLE_VALUE;
import static org.fusesource.jansi.internal.Kernel32.STD_ERROR_HANDLE;
import static org.fusesource.jansi.internal.Kernel32.STD_INPUT_HANDLE;
import static org.fusesource.jansi.internal.Kernel32.STD_OUTPUT_HANDLE;
import static org.fusesource.jansi.internal.Kernel32.WaitForSingleObject;
import static org.fusesource.jansi.internal.Kernel32.readConsoleInputHelper;
//...
public class JansiWinSysTerminal extends AbstractWindowsTerminal<Long> {
//...

If you attempt to use JLine as a JPMS Module then you will get the following error:

Caused by: java.lang.ExceptionInInitializerError: Exception java.lang.IllegalAccessError: class org.jline.terminal.impl.jansi.win.JansiWinSysTerminal (in module org.jline) cannot access class org.fusesource.jansi.internal.Kernel32 (in module org.fusesource.jansi) because module org.fusesource.jansi does not export org.fusesource.jansi.internal to module org.jline [in thread "main"]

A short-term fix would be to roll back to the JPMS configuration of 2.4.0.

@bowbahdoe
Copy link
Contributor

The right fix would be to either decide that yes, org.fusesource.jansi.internal is part of the public api and export it. Or to add a conditional export so that only jline can see it.

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

2 participants