Если вы посмотрите на образец HelloFXML
в репозитории образцов клиента , вы увидите, что он использует типичный файл F XML с контроллером:
<AnchorPane fx:id="pane" ... fx:controller="hellofx.HelloController">
В вашем случае у вас нет контроллера в файле F XML, но вы предоставляете его как:
fxmlLoader.setController(new hellofx.HelloController());
Как вы знаете, FXMLLoader
использует отражение для создания экземпляра контроллера, элементов управления и методы, обнаруженные при разборе файла F XML.
В любом случае, когда вы нажимаете кнопку, которая запускает метод loginAction
, FXMLLoader обрабатывает этот вызов :
MethodHelper.invoke(method, controller, params);
, который использует отражение для обработки такого события.
С GraalVM отражение является проблемой, и вам нужно немного «помочь» ей, предоставив классы / методы / поля, которые в какой-то момент будут использоваться рефлексивно. Узнайте больше об этом здесь .
Клиентский плагин уже позаботится о добавлении основных классов и методов JavaFX. Вы можете увидеть, что добавлено в target/client/x86_64-darwin/gvm/reflectionconfig-x86_64-darwin.json
.
Однако в этот файл необходимо добавить свои собственные классы. Есть два способа сделать это:
- Как и в HelloF XML, через конфигурацию /
reflectionList
вы предоставите пользовательский класс / классы, которые будут использоваться рефлексивно:
<plugin>
<groupId>com.gluonhq</groupId>
<artifactId>client-maven-plugin</artifactId>
<version>${client.plugin.version}</version>
<configuration>
<reflectionList>
<list>hellofx.HelloController</list> <!-- your custom classes -->
</reflectionList>
<mainClass>${mainClassName}</mainClass>
</configuration>
</plugin>
Это приводит к открытию всех методов / полей класса для отражения. Вы увидите результат в файле json как:
{
"name" : "hellofx.HelloController",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredFields" : true,
"allPublicFields" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
}
...
Этого должно быть достаточно, чтобы решить вашу проблему.
- Через файлы конфигурации. Как вы можете прочитать в клиентской документации , вместо этого вы можете добавить файл конфигурации (
reflectionconfig.json
) в META-INF/substrate/config
:
[
{
"name":"hellofx.HelloController",
"methods":[{"name":"loginAction","parameterTypes":["javafx.event.ActionEvent"] }]
}
]
Это тоже исправит . Конечно, это может потребовать добавления других методов, которые есть в контроллере (например, initialize
).
Это откроет для отражения только этот метод, поэтому он будет иметь меньшее влияние на объем памяти и следует за тем, что плагин работает с базовыми классами JavaFX.