Spring3新特性:graalvm打包Springboot+Mybatis

Spring3新特性

graalvm打包Springboot+Mybatis

项目源代码

https://github.com/cmdch2017/SpringNative_Graalvm_Mybatis
在这里插入图片描述

如何安装与运行

安装graalvm与配置环境

首先安装步骤参考这篇博客
https://blog.csdn.net/weixin_38943666/article/details/129505945
其次如何处理反射
https://blog.csdn.net/qq_32740973/article/details/131799510
在这里插入图片描述

运行核心步骤

在这里插入图片描述

1、如上图所示,点击mvn clean

2、如上图所示,点击mvn compile

3、执行反射编译语句
java -agentlib:native-image-agent=config-output-dir=C:\Demos\graalvm\src\main\resources\META-INF\native-image  -jar .\target\graalvm-0.0.1-SNAPSHOT.jar 

4、打开 x64 Native Toogls Command Prompt for VS 并 cd到项目文件夹
mvn -Pnative -DskipTests clean native:compile

5、PowerShell中进入项目target目录下
.\graalvm.exe

遇到的零散问题

问题1

org.apache.catalina.LifecycleException: An invalid Lifecycle transition was attempted ([before_stop]) for component在这里插入图片描述
用不了反射,所以需要这个文件去

package org.wxy.example.sqlite.config;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import cn.hutool.core.util.ClassUtil;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;




/**
 * 反射将所有项目类扫描加入到服务, 大力出奇迹的操作,感觉不太合适,不过先让服务跑起来
 *
 * @author PC
 *
 */
@Component
public class ClassReflectConfig {

	static boolean begin = true;

//	@Value("${scanclass}")
	private Boolean scanclass=true;

	@Autowired
	private ThreadPoolTaskExecutor executorService;

	@PostConstruct
	public void init() {

		if (scanclass) {
			System.err.println("配置文件下 scanclass 开启了生成反射类");
		} else {
			System.err.println("配置文件下 scanclass 关闭了生成反射类");
		}

		synchronized (ClassReflectConfig.class) {
			if (begin && scanclass) {
				begin = false;
				executorService.submit(() -> {
					{
						// 扫描系统第二级开始的包
						String packageName = ClassReflectConfig.class.getPackageName();
						String proPackageName = packageName.substring(0,
								packageName.indexOf(".", packageName.indexOf(".") + 1));

						// 可以在这个地方,添加除了服务以外其他的包,将会加入反射,以供graalvm生成配置
						List<String> asList = Arrays.asList(proPackageName);

						for (String spn : asList) {
							try {
								Set<Class<?>> doScan = ClassUtil.scanPackage(spn);
								for (Class clazz : doScan) {
									handlerClass(clazz);
								}
							} catch (Throwable e) {
								e.printStackTrace();
							}
						}
					}
				});
			}
		}


	}

	private void handlerClass(Class clazz) {
		if (clazz.equals(ClassReflectConfig.class)) {
			// 跳过自己,避免形成循环
			return;
		}

		executorService.submit(() -> {
			try {
				System.err.println("反射注入:" + clazz.getName());
				// 生成所有的构造器
				Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
				// 找到无参构造器然后实例化
				Constructor declaredConstructor = clazz.getDeclaredConstructor();
				declaredConstructor.setAccessible(true);
				Object newInstance = declaredConstructor.newInstance();
				Method[] methods = clazz.getDeclaredMethods();
				for (Method method : methods) {
					try {
						// 实例化成功,那么调用一下
						method.setAccessible(true);
						// graalvm必须需要声明方法
						method.invoke(newInstance);
					} catch (Throwable e) {
					}
				}
				Field[] fields = clazz.getDeclaredFields();
				for (Field field : fields) {
					try {
						field.setAccessible(true);
						field.getType();
						String name = field.getName();
						field.get(newInstance);

					} catch (Throwable e) {
					}
				}
				System.err.println("反射注入完成:" + clazz.getName());
			} catch (Throwable e) {
			}
		});
	}

}

之后报错信息

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'sqliteController': Unsatisfied dependency expressed through field 'personService': Error creating bean with name 'personService': Unsatisfied dependency expressed through field 'dao': Error creating bean with name 'personMapper': Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
        at org.springframework.beans.factory.aot.AutowiredFieldValueResolver.resolveValue(AutowiredFieldValueResolver.java:195) ~[na:na]
        at org.springframework.beans.factory.aot.AutowiredFieldValueResolver.resolveObject(AutowiredFieldValueResolver.java:154) ~[na:na]
        at org.springframework.beans.factory.aot.AutowiredFieldValueResolver.resolve(AutowiredFieldValueResolver.java:143) ~[na:na]
        at org.wxy.example.sqlite.controllers.SqliteController__Autowiring.apply(SqliteController__Autowiring.java:14) ~[na:na]
        at org.springframework.beans.factory.support.InstanceSupplier$1.get(InstanceSupplier.java:83) ~[na:na]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.obtainInstanceFromSupplier(DefaultListableBeanFactory.java:947) ~[mysqlandmybatis.exe:6.0.8]

问题2 报错信息提示无法读取外部 DTD ‘mybatis-3-mapper.dtd’

无法读取外部 DTD ‘mybatis-3-mapper.dtd’, 因为 accessExternalDTD 属性设置的限制导致不允许 ‘http’ 访问。

允许对 ‘http’ 的访问:
如果你确定从 ‘http’ 地址下载 DTD 文件是安全的,可以配置解析器以允许对 ‘http’ 的访问。在SpringbootApplication 中,可以使用以下代码:

System.setProperty("javax.xml.accessExternalDTD", "all");

在这里插入图片描述

问题3 exe文件闪退日志

用powerShell打开

问题4 报错信息有提示http

加上支持http协议的参数

  <build>
    <plugins>
      <plugin>
        <groupId>org.graalvm.buildtools</groupId>
        <artifactId>native-maven-plugin</artifactId>
        <configuration>
          <buildArgs combine.children="append">
            <buildArg>--enable-url-protocols=http</buildArg>
          </buildArgs>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>


  <repositories>
    <repository>
      <id>sonatype-oss-snapshots</id>
      <name>Sonatype OSS Snapshots Repository</name>
      <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </repository>
  </repositories>

问题5 RestController层的问题

org.apache.catalina.LifecycleException: An invalid Lifecycle transition was attempted ([before_stop]) for component [StandardEngine[Tomcat]] in state [INITIALIZED]
        at org.apache.catalina.util.LifecycleBase.invalidTransition(LifecycleBase.java:430) ~[mysqlandmybatis.exe:10.1.8]
        at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:244) ~[mysqlandmybatis.exe:10.1.8]
        at org.apache.catalina.core.StandardService.stopInternal(StandardService.java:491) ~[na:na]
        at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257) ~[mysqlandmybatis.exe:10.1.8]
        at org.apache.catalina.core.StandardServer.stopInternal(StandardServer.java:966) ~[na:na]
        at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257) ~[mysqlandmybatis.exe:10.1.8]
        at org.apache.catalina.util.LifecycleBase.destroy(LifecycleBase.java:293) ~[mysqlandmybatis.exe:10.1.8]
        at org.apache.catalina.startup.Tomcat.destroy(Tomcat.java:507) ~[mysqlandmybatis.exe:10.1.8]
        at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.destroySilently(TomcatWebServer.java:262) ~[mysqlandmybatis.exe:3.0.6]
        at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:141) ~[mysqlandmybatis.exe:3.0.6]
        at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:104) ~[mysqlandmybatis.exe:3.0.6]
        at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:488) ~[mysqlandmybatis.exe:3.0.6]

在这里插入图片描述
或者是下面的Controller层报错
在这里插入图片描述
原因是你没按照网上的教程来,在加了问题1的ClassReflectConfig 内容后,mvn -Pnative -DskipTests clean native:compile之后,你得执行以下语句,注意这里C:\Demos\springboot3-demo3-master\src\main\resources\META-INF\native-image还有.\target\springboot3-demo3-0.0.1-SNAPSHOT.jar的路径看你项目中的路径

java -agentlib:native-image-agent=config-output-dir=C:\Demos\springboot3-demo3-master\src\main\resources\META-INF\native-image  -jar  .\target\springboot3-demo3-0.0.1-SNAPSHOT.jar

在这里插入图片描述

问题6 Mapper层问题

在这里插入图片描述
检查yml文件中是否配置好了

mybatis:
  mapper-locations: classpath:mapper/*.xml
  typeAliasesPackage: org.wxy.example.*.model

问题7 只支持mybaits,不支持mybatis-plus

mybatis-plus暂不支持,官方也回应暂时没有计划支持graalvm

问题8 报错信息中有sqlSessionFactory

@MapperScan(basePackages ="org.wxy.example.*.mapper",sqlSessionFactoryRef = "sqlSessionFactory")

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/159038.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux下非root用户安装CUDA

目录 前言 参考链接 步骤 一. 首先&#xff0c;需要查看系统版本&#xff1a; 二. 安装包下载。 下载CUDA&#xff1a; cuDNN下载 三. 开始安装CUDA和cuDNN 安装CUDA 修改环境变量 安装 cuDNN 查看是否安装成功&#xff0c;输入nvcc -V 前言 由于一些代码实现&…

02-3解析BeautifulSoup

一、基本简介 BeautifulSoup简称&#xff1a;bs4什么是BeatifulSoup&#xff1f;  BeautifulSoup&#xff0c;和lxml一样&#xff0c;是一个html的解析器&#xff0c;主要功能也是解析和提取数据优缺点&#xff1f;  缺点&#xff1a;效率没有lxml的效率高  优点&#xff1…

Transformers实战——Datasets板块

文章目录 一、基本使用1.加载在线数据集2.加载数据集合集中的某一项任务3.按照数据集划分进行加载4.查看数据集查看一条数据集查看多条数据集查看数据集里面的某个字段查看所有的列查看所有特征 5.数据集划分6.数据选取与过滤7.数据映射8.保存与加载 二、加载本地数据集1.直接加…

MARKDOWN

新的改变 我们对Markdown编辑器进行了一些功能拓展与语法支持&#xff0c;除了标准的Markdown编辑器功能&#xff0c;我们增加了如下几点新功能&#xff0c;帮助你用它写博客&#xff1a; 全新的界面设计 &#xff0c;将会带来全新的写作体验&#xff1b;在创作中心设置你喜爱…

vscode 配置 lua

https://luabinaries.sourceforge.net/ 官网链接 主要分为4个步骤 下载压缩包&#xff0c;然后解压配置系统环境变量配置vscode的插件测试 这里你可以选择用户变量或者系统环境变量都行。 不推荐空格的原因是 再配置插件的时候含空格的路径 会出错&#xff0c;原因是空格会断…

YOLOv5 配置C2模块构造新模型

&#x1f368; 本文为[&#x1f517;365天深度学习训练营学习记录博客 &#x1f366; 参考文章&#xff1a;365天深度学习训练营 &#x1f356; 原作者&#xff1a;[K同学啊] &#x1f680; 文章来源&#xff1a;[K同学的学习圈子](https://www.yuque.com/mingtian-fkmxf/zxwb4…

html使用天地图写一个地图列表

一、效果图&#xff1a; 点击左侧地址列表&#xff0c;右侧地图跟着改变。 二、代码实现&#xff1a; 一进入页面时&#xff0c;通过body调用onLoad"onLoad()"函数&#xff0c;确保地图正常显示。 <body onLoad"onLoad()"><!--左侧代码-->…

电磁场与电磁波part2--电磁场的基本规律

1、电流连续性方程的微分形式 表明时变电流场是有散场&#xff0c;电流线是由电荷随时间变化的地方发出或终止的&#xff0c;在正电荷随时间减小的地方就会发出电流线&#xff0c;在正电荷随时间增加的地方就会终止电流线。 2、任何一个标量函数的梯度再求旋度时恒等于零&#…

【uniapp】华为APP真机运行(novas系列)

依华为手机为例&#xff0c;首先数据线连接电脑&#xff0c;然后在手机上做如下操作&#xff1a; 1&#xff09;打开设置 2&#xff09;设置——关于手机 3&#xff09;连续点击软件版本号&#xff0c;此时手机处于开发者模式 4) 回到设置——系统和更新 5&#xff09;点击开…

全球温度数据下载

1.全球年平均温度下载https://www.ncei.noaa.gov/data/global-summary-of-the-year/archive/ 2.全球月平均气温下载https://www.ncei.noaa.gov/data/global-summary-of-the-month/archive/ 3.全球日平均气温下载https://www.ncei.noaa.gov/data/global-summary-of-the-day/ar…

使用Sqoop命令从Oracle同步数据到Hive,修复数据乱码 %0A的问题

一、创建一张Hive测试表 create table test_oracle_hive(id_code string,phone_code string,status string,create_time string ) partitioned by(partition_date string) ROW FORMAT DELIMITED FIELDS TERMINATED BY ,; 创建分区字段partition_date&#xff0c…

【Effective C++ 笔记】(四)设计与声明

【四】设计与声明 条款18 &#xff1a; 让接口容易被正确使用&#xff0c;不易被误用 Item 18: 让接口容易被正确使用&#xff0c;不易被误用 Make interfaces easy to use correctly and hard to use incorrectly. “让接口容易被正确使用&#xff0c;不易被误用”&#xff0…

C语言日记——调试篇

一、调试调试的基本步骤 发现程序错误的存在 以隔离、消除等方式对错误进行定位 确定错误产生的原因 提出纠正错误的解决办法 对程序错误予以改正&#xff0c;重新测试 二、Debug和Release Debug通常称为调试版本&#xff0c;它包含调试信息&#xff0c;并且不作任何优化…

数据结构C语言之线性表

发现更多计算机知识&#xff0c;欢迎访问Cr不是铬的个人网站 1.1线性表的定义 线性表是具有相同特性的数据元素的一个有限序列 对应的逻辑结构图形&#xff1a; 从线性表的定义中可以看出它的特性&#xff1a; &#xff08;1&#xff09;有穷性&#xff1a;一个线性表中的元…

线程状态及线程之间通信

线程状态概述 当线程被创建并启动以后&#xff0c;它既不是一启动就进入了执行状态&#xff0c;也不是一直处于执行状态。在线程的生命周期中&#xff0c; 有几种状态呢&#xff1f;在 java.lang.Thread.State 这个枚举中给出了六种线程状态&#xff1a; 线程状态 导致状态发生…

Objectarx 使用libcurl请求WebApi

因为开发cad需要请求服务器的数据&#xff0c;再次之前我在服务器搭设了webapi用户传递数据&#xff0c;所以安装了libcurl在objectarx中使用数据。 Open VS2012 x64 Native Tools Command Prompt补充地址&#xff1a; 我在此将相关的引用配置图片&#xff0c;cad里面的应用和…

Linux中的进程等待(超详细)

Linux中的进程等待 1. 进程等待必要性2. 进程等待的方法2.1 wait方法2.2 waitpid方法 3. 获取子进程status4. 具体代码实现 1. 进程等待必要性 我们知道&#xff0c;子进程退出&#xff0c;父进程如果不管不顾&#xff0c;就可能造成‘僵尸进程’的问题&#xff0c;进而造成内…

UE的PlayerController方法Convert Mouse Location To World Space

先上图&#xff1a; Convert Mouse Location To World这是PlayerController对象中很重要的方法。 需要说明的是两个输出值。 第一个是World Location&#xff0c;这是个基于世界空间的位置值&#xff0c;一开始我以为这个值和当前摄像机的位置是重叠的&#xff0c;但是打印出来…

kaggle项目部署

目录 流程详细步骤注意事项 流程 修改模块地址打包项目上传到kaggle Datasets创建code文件&#xff0c;导入数据与项目粘贴train.py文件&#xff0c;调整超参数&#xff0c;选择GPUsave version&#xff0c;后台训练查看训练结果 详细步骤 打开kaggle网站&#xff0c;点击da…

号卡分销管理系统搭建

随着移动互联网的发展&#xff0c;各种手机应用层出不穷&#xff0c;其中包括了很多用于企业管理的软件。号卡系统分销管理软件就是其中的一种。它是一种基于移动互联网的企业管理软件&#xff0c;能够帮助企业进行号卡的分销管理&#xff0c;从而提高企业的效率和竞争力。 …