我正在开发一个 JavaFX 应用程序,该应用程序当前是非模块化的。如果我要使我的应用程序模块化,那么我需要对不完全在我指挥下的其他项目进行许多更改。
问题是,如果没有
module-info.java,我就无法使用该模块
java.smartcardio
。幸运的是,Eclipse 允许我手动添加它(下面附有屏幕截图)。
但是每次
Maven Update
之后,我都需要再次手动添加。还有其他更方便的方法吗?
重现问题的代码:
Fx智能卡:
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();
}
}
智能卡服务:
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;
}
}
配置:
<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>
这似乎纯粹是IDE问题。我找不到直接的解决方案,但有两种替代方法来处理它。
首先通过替换手动更改 Eclipse .classpath 文件
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-21">
<attributes>
<attribute name="maven.pomderived" value="true" />
</attributes>
</classpathentry>
与
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-21">
<attributes>
<attribute name="module" value="true" />
<attribute name="limit-modules" value="java.se,jdk.accessibility,jdk.dynalink,jdk.httpserver,jdk.incubator.vector,jdk.jartool,jdk.javadoc,jdk.jconsole,jdk.jshell,jdk.jsobject,jdk.management.jfr,jdk.net,jdk.nio.mapmode,jdk.sctp,jdk.security.auth,jdk.security.jgss,jdk.unsupported,jdk.unsupported.desktop,jdk.xml.dom,java.smartcardio" />
<attribute name="maven.pomderived" value="true" />
</attributes>
</classpathentry>
其次,您可以使用“配置构建路径”功能将模块“java.smartcardio”添加到项目中。
如果您不想一次又一次重复配置构建路径,则每当您执行“Maven > Update Project”时,都需要取消选中“从 pom.xml 更新项目配置”框(默认选中).