| | |
| | | package com.hwtd.mes.collect; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.boot.SpringApplication; |
| | | import org.springframework.boot.autoconfigure.SpringBootApplication; |
| | | |
| | | import javax.swing.JOptionPane; |
| | | import java.net.BindException; |
| | | |
| | | @Slf4j |
| | | @SpringBootApplication |
| | | public class DataAcquisitionApplication { |
| | | |
| | | public static void main(String[] args) { |
| | | SpringApplication.run(DataAcquisitionApplication.class, args); |
| | | SpringApplication application = new SpringApplication(DataAcquisitionApplication.class); |
| | | // 系统托盘图标依赖 AWT:Spring Boot 默认 java.awt.headless=true,这里必须关掉,否则托盘不会显示 |
| | | application.setHeadless(false); |
| | | try { |
| | | application.run(args); |
| | | } catch (Throwable e) { |
| | | // 双击 jar 启动用的是 javaw,没有控制台,启动失败时必须弹窗,否则用户什么都看不到 |
| | | showStartupError(e); |
| | | System.exit(1); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 启动失败提示:写日志 + 弹窗 |
| | | */ |
| | | private static void showStartupError(Throwable error) { |
| | | String message = buildStartupErrorMessage(error); |
| | | try { |
| | | log.error("数据采集器启动失败:{}", message, error); |
| | | } catch (Throwable ignored) { |
| | | // 日志系统还没初始化好时忽略 |
| | | } |
| | | try { |
| | | JOptionPane.showMessageDialog(null, message, "数据采集器启动失败", JOptionPane.ERROR_MESSAGE); |
| | | } catch (Throwable t) { |
| | | // 没有桌面会话时弹不了窗,只能靠日志 |
| | | System.err.println(message); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 组装启动失败提示:端口被占用时给出更明确的处理办法 |
| | | * |
| | | * @param error 启动异常 |
| | | * @return 提示内容 |
| | | */ |
| | | public static String buildStartupErrorMessage(Throwable error) { |
| | | Throwable root = error; |
| | | while (root.getCause() != null && root.getCause() != root) { |
| | | root = root.getCause(); |
| | | } |
| | | String detail = root.getMessage() == null ? root.getClass().getName() : root.getMessage(); |
| | | if (root instanceof BindException |
| | | || detail.contains("already in use") |
| | | || detail.contains("Address already in use")) { |
| | | return "服务端口已被占用,程序可能已经在运行。\n" |
| | | + "请先看任务栏右下角有没有采集器图标(右键 → 退出)," |
| | | + "或在任务管理器里结束对应的 java 进程后再启动。"; |
| | | } |
| | | return "启动失败:" + detail + "\n详细错误请查看日志文件。"; |
| | | } |
| | | } |