1. 用户切换
Linux
用户切换引起的问题。
webuser@s-b4:~$
webuser@s-b4:~$ sudo -i
[sudo] password for webuser:
root@s-b4:~# su webuser
/home/webuser/.rbenv/bin/rbenv: line 49: cd: /root: Permission denied
webuser@s-b4:/root$
刚连接登陆到服务器的时候是webuser
用户,使用sudo -i
切换到root
用户(需要输入密码),接着用su webuser
再切回webuser
用户,注意看会发现此时的webuser
用户和刚进来时候的webuser
用户是不一样的,多了个/root
。
切换到webuser
用户的正确做法是使用exit
命令进行用户回退。可以看到从当前的webuser
第一次exit
会回退到root
,再次exit
会回退到webuser
。此时的webuser
才是刚登陆的webuser
。
webuser@s-b4:/root$ exit
exit
root@s-b4:~# exit
logout
webuser@s-b4:~$
当回到最初的webuser
后,如果再次进行exit
则会退出登陆状态。
webuser@s-b4:~$ exit
logout
Connection closing...Socket close.
Connection closed by foreign host.
Disconnected from remote host(123.57.42.168) at 19:45:48.
Type `help' to learn how to use Xshell prompt.
[C:\~]$
2. 问题描述
SpringBoot
项目直接在初始的webuser
用户下启动没有问题,使用sudo -i
切换到root
用户后,再次使用su webuser
切换到webuser
用户,启动则会报如下异常也会报错,完整异常信息见附录。
Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
at org.hibernate.validator.internal.util.Version.getJavaRelease(Version.java:36)
at org.hibernate.validator.internal.engine.ConfigurationImpl.(ConfigurationImpl.java:119)
at org.hibernate.validator.internal.engine.ConfigurationImpl.(ConfigurationImpl.java:95)
at org.hibernate.validator.HibernateValidator.createGenericConfiguration(HibernateValidator.java:31)
at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:296)
... 35 common frames omitted
3. 问题原因
直接打开报错的源码org.hibernate.validator.internal.util.Version.getJavaRelease
。
/**
* 返回当前运行时的Java版本
*
* @return Java版本是一个整数(例如Java 8 会返回 8)
*/
public static int getJavaRelease() {
// 将返回类似于 1.8
String[] specificationVersion = System.getProperty( "java.specification.version" ).split( "\\." );
return Integer.parseInt( specificationVersion[1] );
}
这里发现会获取系统属性java.specification.version
,这个属性是java
运行时环境规范版本。写一个测试方法在服务器上不同用户下分别运行一下,看一下各自获取到的Java
版本号。
import java.util.Properties;
/**
* @author wangbo
* @date 2019/11/18 20:33
*/
public class Test {
public static void main(String[] args) {
//获取所有的属性
Properties properties = System.getProperties();
//遍历所有的属性
for (String key : properties.stringPropertyNames()) {
if (key.equalsIgnoreCase("java.specification.version")){
System.out.println(key + "===>" + properties.getProperty(key));
return ;
}
}
}
}
编译运行
javac Test.java
java Test
三种用户下分别获取的结果
webuser@s-b4:~$
(1)Test执行结果
java.specification.version===>1.8
(2)java -version结果
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
root@s-b4:~#
(1)Test执行结果
java.specification.version===>1.8
(2)java -version结果
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
webuser@s-b4:/root$
(1)Test执行结果
java.specification.version===>11
(2)java -version结果
openjdk version "11.0.4" 2019-07-16
OpenJDK Runtime Environment (build 11.0.4+11-post-Ubuntu-1ubuntu218.04.3)
OpenJDK 64-Bit Server VM (build 11.0.4+11-post-Ubuntu-1ubuntu218.04.3, mixed mode, sharing)
会发现在第三种用户状态下,获取到的竟然是11,再看源码,必然会报数组越界异常了。
为啥是11?后续再说。
附录
完整异常信息
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'defaultValidator' defined in class path resource [org/springframework/boot/autoconfigure/validation/ValidationAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.validation.beanvalidation.LocalValidatorFactoryBean]: Factory method 'defaultValidator' threw exception; nested exception is javax.validation.ValidationException: Unable to instantiate Configuration.
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:627)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:456)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1321)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1160)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:847)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:312)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1204)
at cn.udesk.kun.Application.main(Application.java:19)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:51)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:52)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.validation.beanvalidation.LocalValidatorFactoryBean]: Factory method 'defaultValidator' threw exception; nested exception is javax.validation.ValidationException: Unable to instantiate Configuration.
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:622)
... 27 common frames omitted
Caused by: javax.validation.ValidationException: Unable to instantiate Configuration.
at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:299)
at org.springframework.boot.validation.MessageInterpolatorFactory.getObject(MessageInterpolatorFactory.java:53)
at org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration.defaultValidator(ValidationAutoConfiguration.java:57)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
... 28 common frames omitted
Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
at org.hibernate.validator.internal.util.Version.getJavaRelease(Version.java:36)
at org.hibernate.validator.internal.engine.ConfigurationImpl.(ConfigurationImpl.java:119)
at org.hibernate.validator.internal.engine.ConfigurationImpl.(ConfigurationImpl.java:95)
at org.hibernate.validator.HibernateValidator.createGenericConfiguration(HibernateValidator.java:31)
at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:296)
... 35 common frames omitted