分类: 未分类

  • SpringBoot下使用OpenCV的MatchTemplate功能

    在Windows下编译OpenCV(如在其他系统下编译,请自行搜索)

    CMake:

    https://cmake.org/download/

    1. 下载zip版本“cmake-3.xx-win64-x64.zip”
    2. 解压到指定目录并添加bin所在目录到环境变量。
    3. 在终端输入“cmake –help”或 “cmake –version”查看是否配置成功。

    MinGW:

    https://sourceforge.net/projects/mingw-w64/files/

    1. 推荐下载 离线版本“x86_64-posix-seh”
    2. 解压到指定目录并将bin目录加入到环境变量
    3. 在终端输入 “gcc –version”。查看是否安装成功。

    OpenCV

    本次 Windows 环境的安装,因此下载OpenCV-4.6.0 Windows 版。

    双击下载好的exe文件,程序会生成 opencv 文件夹。

    这个 opencv 文件夹就是我们后面的编译源文件。

    新建一个文件夹 build_for_vscode ,用于存放我们后面的编译结果。

    下载OpenCV运行库

    下载OpenCV – 4.7.0的Windows版本,运行并制定解压目录。

    (注意,如果这里选择其他版本,请务必在后面的项目依赖用也配置对应的4.7.0版本。)

    然后配置系统的环境变量Path,添加“opencv/build/java/x86/opencv_java470.dll”。

    否则会报类似如下的错误:

    Exception in thread "JavaFX Application Thread" java.lang.UnsatisfiedLinkError: no opencv_java470 in java.library.path: D:\Java\jdk-17.0.8\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Program Files (x86)\VMware\VMware Workstation\bin\;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\NVIDIA Corporation\NVIDIA NvDLISR;C:\Program Files\Git\cmd;C:\Program Files\TortoiseGit\bin;C:\Program Files (x86)\Microsoft SQL Server\160\Tools\Binn\;C:\Program Files\Microsoft SQL Server\160\Tools\Binn\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\;C:\Program Files\Microsoft SQL Server\160\DTS\Binn\;C:\Program Files\Docker\Docker\resources\bin;D:\Java\jdk-1.8\bin;C:\Program Files\JetBrains\IntelliJ IDEA 2021.2\plugins\maven\lib\maven3\bin;C:\Program Files\nodejs\;C:\Windows\System32\Wbem;D:\Redis-x64-3.2.100;C:\Program Files\Go\bin;C:\Program Files\Go\bin;C:\Program Files\OpenSSL-Win64\bin;D:\MinGW-12.2.0\bin;D:\gradle-8.5\bin;D:\hkbea\20231201.PBWMS Enhancement\RmTool\opencv\build\java\x64;C:\Program Files\Tesseract-OCR;C:\Users\cp0612\AppData\Local\Microsoft\WindowsApps;C:\Users\cp0612\AppData\Roaming\npm;C:\Windows\System32\Wbem;C:\Users\cp0612\AppData\Local\Programs\Microsoft VS Code\bin;C:\Users\cp0612\go\bin;C:\Program Files\CMake\bin;.
    	at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2429)
    	at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:818)
    	at java.base/java.lang.System.loadLibrary(System.java:1989)
    	at com.hkbea.pbwms.rmtool.MainApp$1.run(MainApp.java:151)
    	at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457)
    	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    	at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456)
    	at com.sun.glass.ui.InvokeLaterDispatcher$Future.run$$$capture(InvokeLaterDispatcher.java:96)
    	at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java)
    	at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    	at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
    	at java.base/java.lang.Thread.run(Thread.java:833)

    在项目中引入依赖

    依赖版本可以查看这里:https://mvnrepository.com/artifact/org.bytedeco/opencv

    	// https://mvnrepository.com/artifact/org.bytedeco/opencv
    	implementation group: 'org.bytedeco', name: 'opencv', version: '4.7.0-1.5.9'

    请务必注意version需要和所下载的OpenCV运行版本号一致。

    示例代码

    // 加载OpenCV库
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    
    // 读取源图像和模板图像
    Mat sourceImage = Imgcodecs.imread("screenshot.png");
    Mat templateImage = Imgcodecs.imread("template.png");
    
    // 创建结果矩阵
    int resultCols = sourceImage.cols() - templateImage.cols() + 1;
    int resultRows = sourceImage.rows() - templateImage.rows() + 1;
    //Mat resultImage = new Mat(resultRows, resultCols, CvType.CV_32F);
    Mat resultImage = new Mat(resultRows, resultCols, CvType.CV_32FC1);
    
    // 执行模板匹配
    // 注意:这里只是一个简单的示例,实际的模板匹配需要根据具体需求进行参数调整和处理
    /**
     * result 参数:用于存储匹配结果的矩阵,您可以检查这个矩阵来了解匹配的情况。
     * method 参数:指定匹配方法。常见的匹配方法包括 Imgproc.TM_SQDIFF、 Imgproc.TM_SQDIFF_NORMED、Imgproc.TM_CCORR、Imgproc.TM_CCORR_NORMED、Imgproc.TM_CCOEFF 和 Imgproc.TM_CCOEFF_NORMED,它们会影响到匹配结果的精确度和准确度。
     * mask 参数:指定模板的掩码,可以使用它来限制匹配区域,提高匹配的准确度。
     * scale 和 scaleFactor 参数:指定搜索图像和模板图像的缩放比例,可以通过调整这些参数来适应不同尺寸的图像。
     */
    Imgproc.matchTemplate(sourceImage, templateImage, resultImage, Imgproc.TM_CCOEFF_NORMED);
    
    // --------- 处理匹配结果 ----------
    
    //匹配阈值处理
    //double thresholdValue = 0.8;
    //Core.compare(resultImage, new Scalar(thresholdValue), resultImage, Core.CMP_GE);
    
    // 寻找最大和最小匹配值及其位置
    Core.MinMaxLocResult mmr = Core.minMaxLoc(resultImage);
    
    //比对匹配到的图像结果
    double threshold = 0.2; // 设置匹配阈值
    if (mmr.maxVal >= threshold) {
        //log.info("匹配成功");
        System.out.println("匹配成功");
        Point maxLoc = mmr.maxLoc;
        // 在原始图像中画出匹配结果的矩形框
        Rect matchRect = new Rect((int)maxLoc.x, (int)maxLoc.y, templateImage.cols(), templateImage.rows());
        Imgproc.rectangle(sourceImage, matchRect.tl(), matchRect.br(), new Scalar(0, 255, 0), 2);
    
        // 将 Mat 对象转换为 BufferedImage
        //imageView.setImage(SwingFXUtils.toFXImage(matToBufferedImage(resultImage),null));
        BufferedImage resultBuffImage = Mat2BufImg(sourceImage,".png");
        WritableImage rersultWritableImage = SwingFXUtils.toFXImage(resultBuffImage,null);
        File resultImageFile = new File("outputImage.png");
        try {
            ImageIO.write(SwingFXUtils.fromFXImage(rersultWritableImage, null), "png", resultImageFile);
            System.out.println("屏幕截图已保存到: " + resultImageFile.getAbsolutePath()+"; 大小="+resultImageFile.length());
        } catch (IOException e) {
            System.out.println("无法保存屏幕截图: " + e.getMessage());
        }
        imageView.setImage(rersultWritableImage);
    } else {
        // 未找到匹配
        //log.info("匹配失败");
        System.out.println("匹配失败");
    }
    
    // 释放资源
    sourceImage.release();
    templateImage.release();
    resultImage.release();
  • 使用SpringBoot3.2.3[Gradle]整合JavaFX

    环境:JDK1.7

    官方的配置参考指导:https://openjfx.cn/openjfx-docs/#gradle

    第一步:修改Gradle配置,增加JavaFX依赖

    在项目的build.gradle文件中增加JavaFX的插件配置:

    plugins {
    	//JavaFX
    	id 'application'
    	id 'org.openjfx.javafxplugin' version '0.0.13'
    }
    
    //JavaFX配置
    javafx {
    	version = "17.0.2"
    	modules = [ 'javafx.controls', 'javafx.graphics', 'javafx.base', 'javafx.fxml' ]
    }

    版本号可以在这里获取:https://openjfx.cn/dl/

    但是注意一下:

    1、有可能官网上最新的版本号在Maven依赖镜像仓中不存在,我在测试的时候,官网的是17.0.4,但一直无法下载成功,于是改成17.0.2就成功了。

    2、org.openjfx.javafxplugin的version如果太低,则有可能无法匹配到对应的依赖。当时我找的教程是0.0.10,但是一直提示javafx的配置那里一直报灰色(失效),且无法build。

    第二步:创建窗体程序类

    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.AnchorPane;
    import javafx.stage.Stage;
    
    public class MainApp extends Application {
    
        @Override
        public void start(Stage primaryStage) throws Exception {
            AnchorPane anchorPane = new AnchorPane();
            Scene scene = new Scene(anchorPane, 200, 150);
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
    }

    第三步:改造SpringBoot启动类

    import javafx.application.Application;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class RmToolApplication implements CommandLineRunner {
    
    	public static void main(String[] args) {
    		SpringApplication.run(RmToolApplication.class, args);
    	}
    
    	@Override
    	public void run(String... args) throws Exception {
    		Application.launch(MainApp.class, args);
    	}
    
    }
    

    第四步:启动

  • 在安装了OpenWrt的树莓派4B上组建软RAID1,然后进行故障恢复测试,并配置监控的邮件通知

    组建软RAID1

    先插入两个规格相同的存储器,一般会是/dev/sda和/dev/sdb,此时可以使用以下两个命令来查看磁盘情况:

    #查看当前系统磁盘使用情况
    df -h
    #查看磁盘情况
    fdisk -l

    然后使用以下命令对这两个存储器分别进行分区和格式化:

    fdisk /dev/sda

    然后按顺序进行以下操作:

    输入n,回车
    
    输入p,回车
    
    输入1,回车
    
    回车
    
    输入分区大小如+2G
    
    输入wq,回车

    至此新建完sda1,然后再用同样的操作对/dev/sdb进行操作以新建sda2。

    然后在OpenWRT界面中进行软raid1的建立:

    记得要把你的磁盘阵列成员选上,也就是刚刚的/dev/sda1和/dev/sdb1。

    接着如下图所示创建一个挂载点:

    注意:同一个存储器在开机启动时不能被同时挂载,否则会以最后一个挂载为准。

    然后重启设备即可,重启后可以到OpenWRT中查看挂载情况:

    模拟故障

    查看当前RAID的详情:

    mdadm --detail /dev/md0

    使用以下命令让设备分区sdb1模拟故障:

    mdadm --manage /dev/md0 --fail /dev/sdb1

    然后查看软RAID的详情:

    mdadm --detail /dev/md0

    从RAID1阵列中移除sdb1分区:

    mdadm --manage /dev/md0 --remove /dev/sdb1

    再次查看RAID详情:

    mdadm --detail /dev/md0

    从上图中可以看到原来标记faulty的设备信息已经没有看见了。

    接着我们拔掉故障存储器sdb,把存储器sdb插到其他电脑上删除分区,然后再插回到设备上,接着格式化,此时咱们的sdb1又回来了。

    于是使用以下指令进行把用于模拟恢复的设备分区sdb1重新加回到原来的md0软阵列分区中:

    mdadm --add /dev/md0 /dev/sdb1

    执行命令后,可以看到两个存储器正在闪烁并同步数据,使用以下命令可以查看到RAID1的数据正在重建中:

    最后等待重建完毕,在此过程中,/dev/sda1依然能够正常访问:

    若同步完毕,则两个盘的状态都会如下图所示:

    设置RAID的健康监控通知

    在网络上有些人说mdadm的监控配置路径是/etc/mdadm.conf或/etc/mdadm/mdadm.conf,但是我都找不到,然后使用“mdadm –monitor –scan”指令,其提示:

    这是没有配置邮箱地址的提示,那我便创建了/etc/mdadm.conf和/etc/mdadm/mdadm.conf这两个配置文件,结果提示依然没变。

    找了网上资料,说monitor指令需要加-mail参数,加了后又说只允许有一个监控进程:

    然后使用以下指令查看相关进程:

    ps -ef | grep mdadm

    这才得知,原来默认是加载的/var/etc/mdadm.conf文件啊!

    于是便打开/var/etc/mdadm.conf文件,发现又有一句提示:

    然后又看看/etc/config/mdadm这个文件,看到我明明已经修改了:

    但是这里又看到下面的array配置已经成功写到了/var/etc/mdadm.conf文件了。于是心里便想,是不是启动服务时某个脚本创建的呢?所以就到/etc/init.d里面找找相关的启动脚本。

    果真如此!找到了mdadm的启动脚本,编辑他:

    vim /etc/init.d/mdadm

    发现有如下代码片段:

    意思是只有找到sendmail程序时才会在mdadm的配置文件中加入邮箱地址。

    我看了下,没有sendmail,但我已经安装并配置好了msmtp了,所以就修改一下这里:

    mdadm_common() {
            local cfg="$1"
            local email devices
    
    #       if [ -x /usr/sbin/sendmail ]; then
            if [ -x /usr/bin/msmtp ]; then
                    config_get email "$cfg" email
    #               [ -n "$email" ] && printf "MAILADDR %s\n" "$email" >> $CONF
                   [ -n "$email" ] && printf "MAILADDR %s\nMAILFROM %s\n" "$email" "$email" >> $CONF
            fi
    
            config_list_foreach "$cfg" devices append_list_item devices " "
            [ -n "$devices" ] && printf "DEVICE %s\n" "$devices" >> $CONF
    }
    

    然后umount你的分区,再使用 service mdadm restart 命令来服务即可。

    如果配置正常,则你在模拟分区异常的时候,就能够收到如图所示的邮件通知:

    其他

    强制检查时遇到“sh: /usr/lib/sendmail: not found”,则代表你的mdadm默认调用的是sendmail的程序进行邮件发送的,但你的电脑上并没有安装sendmail,所以报了这个错误。此时你如果想继续使用msmtp的话,则可以使用以下指令创建软连接:

    ln -s /usr/bin/msmtp /usr/lib/sendmail

    然后再次执行mdadm的强制测试指令即可:

    mdadm --monitor --scan --test --oneshot
  • 在OpenWRT上配置MSMTP邮件服务并配置QQ邮箱

    先执行msmtp命令看看是否已经安装,如果没有安装,则会如下图所示:

    然后使用以下命令进行安装

    opkg update
    opkg install msmtp

    再次输入msmtp命令,不再有命令错误提示,即代表安装成功。

    使用以下指令测试邮件发送:

    echo -e "Subject: Test\n\nThis is a test email." | msmtp 81408242@qq.com

    此时出现如下提示:

    这是因为安装msmtp服务后未配置邮件服务器引起的,我们使用以下指令进行配置:

    vim /etc/msmtprc

    然后修改成smtp的默认配置参数即可:

    account default
    host smtp.qq.com
    port 587
    tls on
    tls_starttls on
    user 81408242@qq.com
    password *************** #这里换成邮箱授权密码
    from 81408242@qq.com
    auth on
    

    保存后再次使用邮件测试指令进行测试即可:

    echo -e "Subject: Test\r\n\r\nThis is a test email." | msmtp 81408242@qq.com
  • 树莓派安装OpenWRT后安装Docker环境+GitLab

    安装Docker

    更新软件源:

    opkg update

    安装docker进程:

    opkg install dockerd

    安装docker:

    opkg install docker

    安装dockerman:

    opkg install luci-app-dockerman

    安装完毕后,登录OpenWrt界面,应该就可以看到Docker的菜单了:

    点击上图所示的“启动”按钮,即可启动程序Docker服务了。

    然后可以在SSH界面中执行以下命令以查看Docker的相关情况:

    #docker的完整性检查
    docker info
    
    #docker的版本查看
    docker version

    启动命令:

    service dockerd start

    停止命令:

    service dockerd stop

    Docker的空间配置

    默认安装好后docker的空间只有几百M,完全不够。可以到磁盘管理里面,找到对应的硬盘进行编辑。

    上图只是个示例,实际上可能你不是需要在这里新增分区。
    上图圈住的部分是我创建的分区,mmcblk0p3是我本次需要挂在成docker磁盘的分区。mmcblk0p4我是打算作为data分区用于保存实例的持久化数据。

    最后重启设备,再次进入,即可看到如下图所示:

    使用“df -h”可以看到最新的分区情况:

    同理,你也可以使用上述的流程,设置mmcblk0p4为/data挂载点:

    最后应该是这样的:

    安装Arm64版本的GitLab-CE

    (机器配置要大于4g,否则很容易启动不了,报502)

    GitLab-CE是指社区免费版本,使用如下命令安装:

    docker run \
      --detach \
      --restart always \
      --name gitlab-ce \
      --privileged \
      --publish 8022:22 \
      --publish 8080:80 \
      --publish 8443:443 \
      --hostname 192.168.1.1 \
      --env GITLAB_OMNIBUS_CONFIG="nginx['redirect_http_to_https'] = true;" \
      --volume /data/docker/gitlab-ce/conf:/etc/gitlab:z \
      --volume /data/docker/gitlab-ce/logs:/var/log/gitlab:z \
      --volume /data/docker/gitlab-ce/data:/var/opt/gitlab:z \
      yrzr/gitlab-ce-arm64v8:latest

    需要查看gitlab的root初始密码时,可以使用以下命令:

    sudo docker exec -it gitlab-ce grep 'Password:' /etc/gitlab/initial_root_password

    密码文件将在 24 小时后的第一次重新配置运行中自动删除。

    如需配置邮件传输,可以修改以下配置文件/srv/gitlab-ce/conf/gitlab.rb:

    vim /srv/gitlab-ce/conf/gitlab.rb

    配置完成后保存,并使用下面命令进入 gitlab-ce 的 docker 容器:

    docker exec -it gitlab-ce /bin/bash

    然后让gitlab重新加载新的配置文件:

    gitlab-ctl reconfigure

    测试邮件传输是否可用,可先进入控制台:

    gitlab-rails console

    然后在控制台中使用以下命令即可:

    Notify.test_email('收件邮箱','Message Subject','Message Body').deliver_now
  • 在OpenWRT中使用USB网卡桥接Wlan及Lan网络时偶现“br-lan: reveived packet on eth0 with own address as source address”的错误提示

    使用以下命令查看网络端口的相关信息:

    ip addr

    然后返回如下信息:

    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
        inet6 ::1/128 scope host
           valid_lft forever preferred_lft forever
    2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq master br-lan state DOWN group default qlen 1000
        link/ether e4:5f:01:16:9b:b3 brd ff:ff:ff:ff:ff:ff
    3: gre0@NONE: <NOARP> mtu 1476 qdisc noop state DOWN group default qlen 1000
        link/gre 0.0.0.0 brd 0.0.0.0
    4: gretap0@NONE: <BROADCAST,MULTICAST> mtu 1462 qdisc noop state DOWN group default qlen 1000
        link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
    5: erspan0@NONE: <BROADCAST,MULTICAST> mtu 1450 qdisc noop state DOWN group default qlen 1000
        link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
    7: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br-lan state UP group default qlen 1000
        link/ether e4:5f:01:16:9b:b4 brd ff:ff:ff:ff:ff:ff
        inet6 fe80::e65f:1ff:fe16:9bb4/64 scope link
           valid_lft forever preferred_lft forever
    17: br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
        link/ether e4:5f:01:16:9b:b3 brd ff:ff:ff:ff:ff:ff
        inet 192.168.1.1/24 brd 192.168.1.255 scope global br-lan
           valid_lft forever preferred_lft forever
        inet6 fe80::e65f:1ff:fe16:9bb5/64 scope link
           valid_lft forever preferred_lft forever
    54: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br-SIM7600G state UNKNOWN group default qlen 1000
        link/ether b6:09:ba:f2:6a:1f brd ff:ff:ff:ff:ff:ff
    55: br-SIM7600G: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
        link/ether b6:09:ba:f2:6a:1f brd ff:ff:ff:ff:ff:ff
        inet 192.168.225.54/24 brd 192.168.225.255 scope global br-SIM7600G
           valid_lft forever preferred_lft forever
        inet6 fe80::b409:baff:fef2:6a1f/64 scope link
           valid_lft forever preferred_lft forever

    由上述信息可以看到,ip信息中的br-lan和eth0的mac地址一样的,分析原因可能是由于安装好OpenWRT并配置完USB网卡的桥接网络《br-lan》时,br-lan的mac地址默认可能会出现和其他网络端口的mac地址一样的情况。

    因此,我们只需要更改其br-lan的mac地址即可解决这个问题。

    登录OpenWRT的管理界面,找到如下位置:

    如上图所示,我讲mac地址最后的B3改成了B5,于是重启设备生效后,该问题解决。

    补充

    经过之前的操作后,这个问题已经有一段时间消失没有出现了。但最近又再出现了,使用“ip addr”命令查看mac地址也没有存在一样的情况。这个时候可以使用以下方法尝试打开br-lan的STP功能:

    #查看STP的开启情况
    brctl show
    #为br-lan开启STP
    brctl stp br-lan on

    然后再次查看STP的开启情况,此时应该已经开启成功,如下图所示:

  • 在Windows下使用JBoss的standalone模式运行打成war包的SrpingBoot时使用外部配置文件

    先在SpringBoot项目中新增一个MyApplicationContext.java文件,内容如下:

    import org.springframework.context.ApplicationContextInitializer;
    import org.springframework.context.ConfigurableApplicationContext;
    import org.springframework.boot.env.YamlPropertySourceLoader;
    import org.springframework.core.env.PropertySource;
    import org.springframework.core.io.InputStreamResource;
    
    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    
    public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    
        @Override
        public void initialize(ConfigurableApplicationContext applicationContext) {
            String activeProfile = applicationContext.getEnvironment().getProperty("spring.profiles.active");
            if("uat".equals(activeProfile) || "prod".equals(activeProfile)){
                YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
                try {
                    String jbossHome = (String) applicationContext.getEnvironment().getSystemEnvironment().get("JBOSS_HOME");
                    PropertySource<?> propertySource = loader.load("externalConfiguration", new InputStreamResource(Files.newInputStream(Paths.get(jbossHome+"\\standalone\\configuration\\application-druid.yml")))).get(0);
                    applicationContext.getEnvironment().getPropertySources().addLast(propertySource);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
    
        }
    }

    然后再resources的META-INF目录中创建一个spring.factories文件,内容需要指向到刚刚创建的MyApplicationContextInitializer类文件:

    在系统中新建JBOSS_HOME环境并指向JBOSS的根目录:

    然后在jboss的standalone\configuration目录中放置对应的配置文件:

    然后启用jboss服务,此时springboot的war应用会优先到这个configuration目录中寻找对应的application配置文件,找不到时便会使用war包中的配置文件。

  • 记一次使用VMWare 16.1无法安装Win10的问题

    创建了一个虚拟机,ISO为Win10的官方镜像,启动后显示下面的画面后就自动关闭了:

    然后尝试使用物理U盘启动,结果也会显示如下弹窗:

    创建了一个虚拟机,ISO为Win10的官方镜像,启动后显示下面的画面后就自动关闭了:

    然后尝试使用物理U盘启动,结果也会显示如下弹窗:

    搜索资料后,可能是由于未开启CPU的虚拟化功能引起的,请确保虚拟机的设置中CPU已如下图所示:

    然后启动虚拟机,但又有如下提示:

    此时有三种原因,请顺序进行:

    原因一:电脑是否支持Inter的VT-x技术并且在BIOS中已经开启?

    解决方法:请自行搜索网络资料,这个问题比较基础,开启成功的话,Windows任务管理器的性能板块可以找到以下提示。

    原因二:Windows的Hyper-V功能与VMWare的功能冲突。

    解决方法:请确保Windows的功能开关如下图所示:

    并确保相关的Service服务已经禁用,如下图所示:

    原因三:虚拟机访问物理资源时一定是需要通过VMM去建立一个虚拟的Ring0权限,内核隔离开启后, 默认会启动hybrid-v, 这个东西和虚拟机是冲突的。

    解决方法:打开“Windows安全中心>设备安全性>内核隔离”,确保是关闭的,如下图所示:

    OK,至此问题解决,顺利进入安装程序:

  • 树莓派zero w在烧录好镜像后配置wifi

    方法一:

    用读卡器读取刚刚烧录好的SD卡,然后再SD卡的根目录创建一个文件:wpa_supplicant.conf

    country=CN
    update_config=1
    ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
    
    network={
    	ssid="RaspberryPi-OpenWrt"
    	psk="woshishabi"
    	key_mgmt=WPA-PSK
    }
    • ssid:WiFi的名称
    • psk:WiFi的密码
    • key_mgmt:加密方式,以实际情况填写,家用目前通常为WPA/WPA2,我这里填写WPA-PSK即可。

    注意保存的时候要用unix的文件格式,不然不生效。

    方法二:

    直接在pi zero中修改文件“/etc/wpa_supplicant/wpa_supplicant.conf”并在末尾添加如下代码:

    network{
    	ssid="z"                 #WIFI名
    	psk="helloworld123"         #WIFI密码
    	scan_ssid=1
    }

    其他

    记得重启,然后可以使用以下命令来查看是否wifi已经生效:

    ifconfig wlan0

    如果仍然连接不上,可以使用以下指令查看pi所能scan得到的所有WIFI:

    sudo iwlist wlan0 scan | grep ESSID

    注意:zero的wifi是2.4G的,如果你的路由器wifi是5G的,则会出现scan不到的情况。

  • JBOSS EAP 7.4 修改在standalone下默认的HTTPS证书

    jboss在standalone模式下的配置文件是在/standalone/configuration/standalone.xml,所以接下来的操作都在这个文件中进行。

    确认JBOSS的HTTPS启用情况

    打开配置文件,确保以下配置中的https的配置是存在的,且是你想要的:

        <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
            <socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
            <socket-binding name="http" port="${jboss.http.port:8080}"/>
            <socket-binding name="https" port="${jboss.https.port:8443}"/>
            <socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
            <socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>
            <socket-binding name="txn-recovery-environment" port="4712"/>
            <socket-binding name="txn-status-manager" port="4713"/>
            <outbound-socket-binding name="mail-smtp">
                <remote-destination host="${jboss.mail.server.host:localhost}" port="${jboss.mail.server.port:25}"/>
            </outbound-socket-binding>
        </socket-binding-group>

    配置你的SSL证书

    找到security-realms对应的配置:

            <security-realms>
                <security-realm name="ManagementRealm">
                    <authentication>
                        <local default-user="$local" skip-group-loading="true"/>
                        <properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
                    </authentication>
                    <authorization map-groups-to-roles="false">
                        <properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
                    </authorization>
                </security-realm>
                <security-realm name="ApplicationRealm">
                    <server-identities>
                        <ssl>
                            <keystore path="application.keystore" relative-to="jboss.server.config.dir" keystore-password="password" alias="server" key-password="password" generate-self-signed-certificate-host="localhost"/>
                        </ssl>
                    </server-identities>
                    <authentication>
                        <local default-user="$local" allowed-users="*" skip-group-loading="true"/>
                        <properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
                    </authentication>
                    <authorization>
                        <properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
                    </authorization>
                </security-realm>
            </security-realms>

    在security-realms内增加你的security-realm,如:MySecurityRealm(其实以下代码是拷贝ApplicationRealm后修改其keystore的配置以及增加了truststore的配置,具体见高亮行)

                <security-realm name="MySecurityRealm">
                    <server-identities>
                        <ssl>
                            <keystore path="D:\xxx\yourKeyStore.jks" keystore-password="123456" alias="yourKeyAlias" key-password="123456"/>
                        </ssl>
                    </server-identities>
                    <authentication>
                        <local default-user="$local" allowed-users="*" skip-group-loading="true"/>
                        <properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
                        <truststore path="D:\xxx\yourKeyStore.jks" keystore-password="123456"/>
                    </authentication>
                    <authorization>
                        <properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
                    </authorization>
                </security-realm>

    修改你需要配置的subsystem对应的security-realm

    大家一般都是根目录部署,所以一般是搜索“default-host”关键字来找到对应的subsystem。

            <subsystem xmlns="urn:jboss:domain:undertow:12.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other" statistics-enabled="${wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}">
                <buffer-cache name="default"/>
                <server name="default-server">
                    <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
                    <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
                    <host name="default-host" alias="localhost">
                        <location name="/" handler="welcome-content"/>
                        <http-invoker security-realm="ApplicationRealm"/>
                    </host>
                </server>
                <servlet-container name="default">
                    <jsp-config/>
                    <websockets/>
                </servlet-container>
                <handlers>
                    <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
                </handlers>
            </subsystem>

    从上述代码片段中可以找到对应的“security-realm”的名称是“ApplicationRealm”,将他修改成“MySecurityRealm”。

    重启JBOSS

    重启以让配置生效。