I'm working on a JavaFX application which is currently non-modular. If I would make my application modular then I would need to make many changes in other projects that are not fully under my command.
The problem is that I can't use the module java.smartcardio without a module-info.java. Luckily, Eclipse allows me to add it manually (screenshot attached below).
But after each Maven Update, I need to add it manually again. Is there another more convenient way to do it?
Code to reproduce the issue:
FxSmartCard:
package org.example.fxsmartcard;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import javafx.scene.control.Button;
import java.util.List;
import javax.smartcardio.CardException;
import javax.smartcardio.CardTerminal;
import org.example.smartcardservice.SmartCardServices;
public class FxSmartCard extends Application {
private SmartCardServices cardServices;
public FxSmartCard() {
super();
this.cardServices = new SmartCardServices();
}
@Override
public void start(Stage stage) {
Label title = new Label("JavaFX meets SmartCard World!");
title.setStyle("-fx-font-size: 32px;");
final ComboBox < String > terminalComboBox = new ComboBox < String > ();
List < CardTerminal > terminals = null;
Button connect = new Button("Connect");
try {
terminals = cardServices.getTerminals();
if (terminals != null && terminals.size() > 0) {
for (CardTerminal terminal: terminals) {
terminalComboBox.getItems().add(terminal.getName());
}
terminalComboBox.getSelectionModel().selectFirst();
final List < CardTerminal > terminalList = terminals;
connect.setOnAction(e -> {
CardTerminal selectedTerminal = cardServices.getCardReader(terminalList,
terminalComboBox.getSelectionModel().getSelectedItem());
try {
cardServices.connectToCard(selectedTerminal);
} catch (CardException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
});
} else {
terminalComboBox.setValue("No Terminal present");
connect.setDisable(true);
}
} catch (CardException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
GridPane gridpane = new GridPane();
GridPane.setConstraints(terminalComboBox, 1, 0);
GridPane.setConstraints(connect, 2, 0);
gridpane.getChildren().addAll(terminalComboBox, connect);
VBox layout = new VBox(10, title, gridpane);
layout.setPadding(new Insets(12));
Scene scene = new Scene(layout);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
SmartCardServices:
package org.example.smartcardservice;
import java.util.List;
import javax.smartcardio.CardException;
import javax.smartcardio.CardTerminal;
import javax.smartcardio.TerminalFactory;
public class SmartCardServices {
public List < CardTerminal > getTerminals() throws CardException {
TerminalFactory factory = TerminalFactory.getDefault();
return factory.terminals().list();
}
public void connectToCard(CardTerminal terninalSource) throws CardException {
terninalSource.connect("*");
}
public CardTerminal getCardReader(List < CardTerminal > terminals, String name) {
for (CardTerminal terminal: terminals) {
if (terminal.getName().equals(name)) {
return terminal;
}
}
return null;
}
}
Configuration:
<project xmlns = "http://maven.apache.org/POM/4.0.0"
xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi: schemaLocation = "http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>JavaFXmeetsSmartCard</groupId>
<artifactId>JavaFXmeetsSmartCard</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>21.0.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>21</source>
<target>21</target>
</configuration>
</plugin>
</plugins>
</build>
</project>


--add-modules java.smartcardioargument (as suggested by dan1st) to see if Eclipse can pick that up.<compilerArgs>may not work.java.smartcardiomodule is in the standard JRE it is not added to the module graph by default by the JRE, so you need to add it manually for both compilation and execution--add-module java.smartcardiofor bothjavacandjava. In Idea you can add the module tojavacin an IDE setting, but the setting is overwritten by a maven import, so you have to re-add the setting after each import. Works apart from that.