Я работаю над приложением, над которым я работаю. решил добавить телеграмм-бота, чтобы давать некоторую удаленную информацию. Когда я запускаю приложение из IDE (в настоящее время я использую IntelliJ IDEA), все работает нормально, как только я создаю исполняемую версию того же приложения, бот Telegram перестает работать без каких-либо исключений, и я не могу понять, что я я делаю неправильно.
Теперь, чтобы изолировать проблему, я создал фиктивный проект, который реализует только бот Telegram (которого я извлек из первого проекта), но поведение такое же: из IDE нет проблем, из исполняемого файла бот не работает.
В следующем разделе вы можете найти все подробности о коде и всех зависимостях, которые я использую.
По сути, я создал проект JavaFX, созданный только одна сцена с двумя кнопками
- Подключиться: используется для открытия соединения с ботом Telegram
- Отправить: используется для отправки «Тестового» сообщения по каналу бота.
Код
Здесь вы можете найти класс контроллера FX:
Код: Выделить всё
package com.example.telegrambotui;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Label;
import javafx.stage.Stage;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Optional;
public class HelloController {
@FXML
private Label welcomeText;
private TelegramBot telegramBot;
@FXML
protected void connectClick() throws IOException {
try {
telegramBot = new TelegramBot("My_test_bot");
welcomeText.setText("Connected");
} catch (Exception e) {
File file = new File("C:\\Users\\luca-\\IdeaProjects\\TelegramBotUI\\Installer\\ConnectException.txt");
file.createNewFile();
PrintWriter pw = new PrintWriter(file);
e.printStackTrace(pw);
}
}
@FXML
protected void onTestButtonClick() throws IOException {
try {
telegramBot.sendMessage("Test");
welcomeText.setText("Sent \"Test\"");
} catch (TelegramApiException e) {
welcomeText.setText("Excetion!!");
fireAlarm(Alert.AlertType.ERROR, HelloApplication.stage, "Error", "Connection error!", e.getMessage());
File file = new File("C:\\Users\\luca-\\IdeaProjects\\TelegramBotUI\\Installer\\TestButtonException.txt");
file.createNewFile();
PrintWriter pw = new PrintWriter(file);
e.printStackTrace(pw);
pw.close();
}
}
private Optional fireAlarm(Alert.AlertType type, Stage owner, String title, String headerText, String contentText) {
Alert alert = new Alert(type);
alert.initOwner(owner);
alert.setTitle(title);
alert.setContentText(contentText);
if (!headerText.equals("")) {
alert.setHeaderText(headerText);
}
return alert.showAndWait();
}
}
Код: Выделить всё
package com.example.telegrambotui;
import org.telegram.telegrambots.bots.TelegramLongPollingBot;
import org.telegram.telegrambots.meta.TelegramBotsApi;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.updatesreceivers.DefaultBotSession;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
public class TelegramBot extends TelegramLongPollingBot {
private final static HashMap AvailableBots = new HashMap(){{
put("My_test_bot", new TelegramChannel("My_test_bot", "Here I've put the bot Token"));
}};
private TelegramChannel telegramChannel;
private final String INIT;
private final String HELLO_WORLD = "/hello";
private final String IS_ALIVE = "/alive";
private final List COMMANDS = Arrays.asList( IS_ALIVE, HELLO_WORLD);
private TelegramBotsApi telegramBotsApi;
public TelegramBot(String channel) throws TelegramApiException {
telegramChannel = AvailableBots.get(channel);
telegramBotsApi = new TelegramBotsApi(DefaultBotSession.class);
telegramBotsApi.registerBot(this);
INIT = "[b][" + telegramChannel.username() + "][/b]\n";
}
public static String[] getAvailableBot() {
String[] bots = new String[AvailableBots.keySet().size()];
int i = 0;
for(String k: AvailableBots.keySet()){
bots[i] = k;
i++;
}
return bots;
}
@Override
public void onUpdateReceived(Update update) {
if (update.hasChannelPost() && update.getChannelPost().hasText()) {
if (COMMANDS.contains(update.getChannelPost().getText())){
try {
switch (update.getChannelPost().getText()){
case HELLO_WORLD -> sendMessage("Hello World!");
case IS_ALIVE -> sendMessage("I'm alive!!");
}
} catch (TelegramApiException e) {
throw new RuntimeException(e);
}
}
}
}
public void sendMessage(String mex) throws TelegramApiException {
if(!mex.startsWith(INIT)){
mex = INIT + mex;
}
SendMessage toSend = new SendMessage(telegramChannel.chat_id(), mex);
toSend.enableHtml(true);
execute(toSend);
}
@Override
public String getBotUsername() {
return telegramChannel.username();
}
@Override
public String getBotToken() {
return telegramChannel.token();
}
}
Здесь вы можете найти все зависимости:
Зависимости
А это файл артефактов:
Артефакты, часть 1
Артефакты, часть 2
Исполняемый скриптЧтобы сгенерировать исполняемый файл, я использую следующий скрипт:
Код: Выделить всё
jpackage -t exe --name "TelegramBotUI" --icon ".\MyIcon.ico" --input "../out/artifacts/TelegramBotUI_jar" --dest "./" --main-jar "TelegramBotUI.jar" --main-class "com.example.telegrambotui.HelloApplication" --module-path "C:\Program Files\Java\javafx-jmods-17.0.2" --add-modules javafx.controls,javafx.fxml --win-menu --win-dir-chooser
Я думаю, что я делаю некоторые ошибки при создании исполняемого файла, потому что из IDE приложение работает без проблем.
Я пытался изменить версию бота Telegram на новую (6.9.7.1), но ничего не получилось изменилось.
Что я делаю не так?
[EDIT 1]
Здесь вы можете найти класс приложения:
Код: Выделить всё
package com.example.telegrambotui;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloApplication extends Application {
public static Stage stage;
@Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
this.stage = stage;
stage.setOnCloseRequest(event -> {
System.exit(0);
});
Scene scene = new Scene(fxmlLoader.load(), 320, 240);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
Исключением является то, что я нажимаю кнопку подключиться, а затем, когда я нажимаю кнопку < em>Test бот должен опубликовать на канале сообщение «Test»; если я написал /hello или /alive по каналу, бот должен ответить соответственно сообщением «Привет» или «Я жив».
По сути проблема в том, что бот из исполняемого приложения делает не отвечать без каких-либо исключений.
[EDIT 2]
Следуя советам в комментарии, я добавил UncaughtExceptionHandler в класс приложения, и теперь, когда я нажимаю кнопку подключения, я сталкиваюсь с этим исключением:
Код: Выделить всё
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(Unknown Source)
at javafx.fxml/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(Unknown Source)
at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
at javafx.base/javafx.event.Event.fireEvent(Unknown Source)
at javafx.graphics/javafx.scene.Node.fireEvent(Unknown Source)
at javafx.controls/javafx.scene.control.Button.fire(Unknown Source)
at javafx.controls/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(Unknown Source)
at javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(Unknown Source)
at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(Unknown Source)
at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
at javafx.base/javafx.event.Event.fireEvent(Unknown Source)
at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Unknown Source)
at javafx.graphics/javafx.scene.Scene.processMouseEvent(Unknown Source)
at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Unknown Source)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Unknown Source)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(Unknown Source)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(Unknown Source)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(Unknown Source)
at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(Unknown Source)
at javafx.graphics/com.sun.glass.ui.View.notifyMouse(Unknown Source)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.javafx.reflect.Trampoline.invoke(Unknown Source)
at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(Unknown Source)
at javafx.fxml/com.sun.javafx.fxml.MethodHelper.invoke(Unknown Source)
... 47 more
Caused by: java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
at org.telegram.telegrambots.bots.DefaultAbsSender.(DefaultAbsSender.java:66)
at com.example.telegrambotui.HelloController.connectClick(HelloController.java:24)
... 57 more
Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
... 59 more
Подробнее здесь: https://stackoverflow.com/questions/782 ... e-problems
Мобильная версия