我创建了一个访问MySQL数据库的Spring Boot应用程序。
如果我用
运行它mvn spring-boot:run
一切正常。
但是,如果我用
打包应用程序mvn clean package
我得到一个NullPointerException:
java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:803) [spring-boot-1.4.1.RELEASE.jar!/:1.4.1.RELEASE]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:784) [spring-boot-1.4.1.RELEASE.jar!/:1.4.1.RELEASE]
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:771) [spring-boot-1.4.1.RELEASE.jar!/:1.4.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) [spring-boot-1.4.1.RELEASE.jar!/:1.4.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1186) [spring-boot-1.4.1.RELEASE.jar!/:1.4.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175) [spring-boot-1.4.1.RELEASE.jar!/:1.4.1.RELEASE]
at de.conbord.trms.Application.main(Application.java:20) [classes!/:1.0-SNAPSHOT]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_102]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_102]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_102]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_102]
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) [trms-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) [trms-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) [trms-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:58) [trms-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
Caused by: java.lang.NullPointerException: null
at de.conbord.trms.controller.TokenBuilder.createToken(TokenBuilder.java:17) ~[classes!/:1.0-SNAPSHOT]
at de.conbord.trms.api.CheckToken.createNewToken(CheckToken.java:66) ~[classes!/:1.0-SNAPSHOT]
at de.conbord.trms.api.CheckToken.checkValidToken(CheckToken.java:41) ~[classes!/:1.0-SNAPSHOT]
at de.conbord.trms.controller.TokenLoader.run(TokenLoader.java:41) ~[classes!/:1.0-SNAPSHOT]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:800) [spring-boot-1.4.1.RELEASE.jar!/:1.4.1.RELEASE]
... 14 common frames omitted
认为应用程序可以访问数据库,因为我没有获得“拒绝访问”错误,但无法获取数据。
为了完整性,这里是我的pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.conbord</groupId>
<artifactId>trms</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<packaging>jar</packaging>
<dependencies>
<!-- Spring Boot JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<!-- lombock -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.8</version>
</dependency>
<!-- Thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>false</optional>
</dependency>
<!-- Apache Commons -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<!-- Spring Boot Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- MySQL Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.4.1.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
CheckToken.java
@Component
public class CheckToken {
private final ConfigurationRepository repository;
private final TokenRepository tokenRepository;
private static final Logger log = LoggerFactory.getLogger(Application.class);
@Autowired
public CheckToken(ConfigurationRepository repository, TokenRepository tokenRepository) {
this.repository = repository;
this.tokenRepository = tokenRepository;
}
public void checkValidToken() {
Configuration configuration = this.repository.findByUserName("ADI");
Token token = this.tokenRepository.findOne(1L);
if (token == null) {
token = createNewToken(configuration);
this.tokenRepository.save(token);
} else {
Long tokenId = token.getId();
Pattern pattern = Pattern.compile("(\\d+)");
Matcher matcher = pattern.matcher(token.getValidTo());
if (matcher.find()) {
Long endDate = Long.parseLong(matcher.group(1));
Date tokenEndDate = new Date(endDate);
Date currentDate = Calendar.getInstance().getTime();
if (currentDate.after(tokenEndDate)) {
TokenBuilder tokenBuilder = new TokenBuilder();
token = tokenBuilder.createToken(configuration);
token.setId(tokenId);
this.tokenRepository.save(token);
}
}
}
}
private Token createNewToken(Configuration configuration) {
TokenBuilder tokenBuilder = new TokenBuilder();
Token token = tokenBuilder.createToken(configuration);
token.setId(1L);
return token;
}
}
TokenBuilder.java
package de.conbord.trms.controller;
import de.conbord.trms.entity.Configuration;
import de.conbord.trms.entity.Token;
import org.springframework.http.HttpEntity;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
public class TokenBuilder {
public Token createToken(Configuration configuration) {
String authString = "SIP sip_username=" + configuration.getUserName()
+ " sip_password=" + configuration.getUserPasswort()
+ " sip_database=" + configuration.getDbName()
+ " app_key=" + configuration.getAppGUID();
String jsonObject = "{\"AppliesTo\":\"localhost:808/staffitprowebAPI/\", \"TokenType\":\"http://staffITpro.com/tokens/staffITproSecurityToken/type\"}";
String url = configuration.getUrl() + "Token/";
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("Accept", "application/json");
headers.add("Content-Type", "application/json");
headers.add("Authorization", authString);
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
HttpEntity<String> request = new HttpEntity<>(jsonObject, headers);
return restTemplate.postForObject(url, request, Token.class);
}
}
配置对象保存在数据库中。
所以现在我不明白为什么如果从jar启动应用程序,我会得到这个例外。
为什么我无法在jar中访问数据库中的配置?
答案 0 :(得分:0)
看起来configuration
对象为空?可能你在运行jar时没有传递相同的参数,就像maven运行时一样?