I'm trying to run a program inside of an .jar file
. To create the .jar file
inside of te projects target folder I used the command mvn clean package spring-boot:repackage
.
After I start the program with java -jar middleware-0.0.1-SNAPSHOT.jar
an error message appears.
The entire error message:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v0.0.1-SNAPSHOT)
08:33:38.573 [main] INFO middleware.Main - Starting Main v0.0.1-SNAPSHOT using Java 1.8.0_192 on JPR-NB with PID 14832 (C:\Projekte\middleware\de.ifd.middleware-0.0.1-SNAPSHOT\target\middleware-0.0.1-SNAPSHOT.jar started by MFI in C:\Projekte\middleware\de.ifd.middleware-0.0.1-SNAPSHOT\target)
08:33:38.583 [main] INFO middleware.Main - No active profile set, falling back to 1 default profile: "default"
08:33:39.489 [main] WARN o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [middleware.Main]; nested exception is java.io.FileNotFoundException: class path resource [de/ifd/remote/DatabaseService.class] cannot be opened because it does not exist
08:33:39.532 [main] ERROR o.s.boot.SpringApplication - Application run failed
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [middleware.Main]; nested exception is java.io.FileNotFoundException: class path resource [de/ifd/remote/DatabaseService.class] cannot be opened because it does not exist
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:189)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:331)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:247)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:311)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:112)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:746)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:164)
at middleware.Main.main(Main.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:108)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88)
Caused by: java.io.FileNotFoundException: class path resource [de/ifd/remote/DatabaseService.class] cannot be opened because it does not exist
at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:199)
at org.springframework.core.type.classreading.SimpleMetadataReader.getClassReader(SimpleMetadataReader.java:55)
at org.springframework.core.type.classreading.SimpleMetadataReader.<init>(SimpleMetadataReader.java:49)
at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:103)
at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.createMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:86)
at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.getMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:73)
at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:81)
at org.springframework.context.annotation.ConfigurationClassParser.asSourceClass(ConfigurationClassParser.java:696)
at org.springframework.context.annotation.ConfigurationClassParser$SourceClass.getInterfaces(ConfigurationClassParser.java:1024)
at org.springframework.context.annotation.ConfigurationClassParser.processInterfaces(ConfigurationClassParser.java:386)
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:332)
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:250)
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:199)
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:304)
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:250)
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:207)
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:175)
... 20 common frames omitted
The resource the program was not able to find is located inside another project. I referenced the remote project inside the Java Build Path and inside my pom.xml
.
Project dependency inside of pom.xml
:
<dependency>
<groupId>remote</groupId>
<artifactId>remote</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>C:\Users\mfi\Downloads\LaunchableJar\remote.jar</systemPath>
</dependency>
The DatabaseService.class
is an interface which contains method I can call over network using JSON RPC.
The interface gets implemented only once inside my project. Inside the DatabaseServiceImpl.class
:
package middleware;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import javax.annotation.Resource;
import org.hibernate.Session;
import org.hibernate.jdbc.ReturningWork;
import org.hibernate.jdbc.Work;
import org.springframework.stereotype.Service;
import com.googlecode.jsonrpc4j.spring.AutoJsonRpcServiceImpl;
import de.ifd.remote.ServiceInformation;
import de.ifd.remote.ServiceSystem;
import de.ifd.remote.UserSettings;
/**
* Implementation of the ServiceInterface. This class gets called over JSON RPC
* by the Service-Ticket-App.
*
* @author MFI
*
*/
@Service
@AutoJsonRpcServiceImpl()
public class DatabaseServiceImpl implements de.ifd.remote.DatabaseService {
@Override
public List<ServiceInformation> getServiceInformations() {
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
ReturningWork<List<ServiceInformation>> returningWork = new ReturningWork<List<ServiceInformation>>() {
@Override
public List<ServiceInformation> execute(Connection connection) throws SQLException {
List<ServiceInformation> returnList = new ArrayList<>();
// read data from database
PreparedStatement stmt = connection.prepareStatement("SELECT * FROM BCSTASKS_SERVICE");
ResultSet rs = stmt.executeQuery();
// Cycle trough each result
while (rs.next()) {
// Create a new ServiceInformation with the name and description
ServiceInformation tempInformation = new ServiceInformation(rs.getString("NAME"),
rs.getString("ATTACHMENTCOMPONENT"), new ArrayList<>(),
rs.getBoolean("WASSHOWN"));
// Add the ServiceInformation to the list
returnList.add(tempInformation);
}
stmt.close();
return returnList;
}
};
return session.doReturningWork(returningWork);
}
}
@Override
public List<ServiceInformation> getNewServiceInformations(List<ServiceSystem> userSystemList) {
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
ReturningWork<List<ServiceInformation>> returningWork = new ReturningWork<List<ServiceInformation>>() {
@Override
public List<ServiceInformation> execute(Connection conn) throws SQLException {
List<ServiceInformation> returnList = new LinkedList<>();
// Read data from database
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM BCSTASKS_SERVICE");
ResultSet rs = stmt.executeQuery();
// Cycle trough each result
while (rs.next()) {
List<ServiceSystem> ticketSystemList = Database
.getSystemListFromTicket(rs.getString("IFD_PRODUKTBESTANDTEILE"));
for (int i = 0; i < ticketSystemList.size(); i ) {
for (int j = 0; j < userSystemList.size(); j ) {
if (ticketSystemList.get(i).getSystem() == userSystemList.get(j).getSystem()
&& rs.getString("STATE").toLowerCase().contains("neu")) {
// Add new Service information to the list
returnList.add(new ServiceInformation(rs.getString("NAME"),
rs.getString("ATTACHMENTCOMPONENT"),
Database.getSystemListFromTicket(rs.getString("IFD_PRODUKTBESTANDTEILE")),
rs.getBoolean("WASSHOWN")));
}
}
}
}
stmt.close();
return returnList;
}
};
return session.doReturningWork(returningWork);
}
}
@Override
public int getServiceInformationsSize() {
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
ReturningWork<Integer> returningWork = new ReturningWork<Integer>() {
Integer size = 0;
@Override
public Integer execute(Connection conn) throws SQLException {
// read data from database
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM DBO.BCSTASKS_SERVICE");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
// Ticket found in the database = 1 Size
size ;
}
stmt.close();
return size;
}
};
return session.doReturningWork(returningWork);
}
}
@Override
public void setNewServiceInformationsToShown(List<ServiceInformation> newServiceInformationList) {
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
session.doWork(new Work() {
@Override
public void execute(Connection conn) throws SQLException {
for (ServiceInformation serviceInfo : newServiceInformationList) {
// Sets all Service information with the Status Neu to Shown
PreparedStatement stmt = conn.prepareStatement(
"UPDATE DBO.BCSTASKS_SERVICE SET WASSHOWN = 1 WHERE NAME = ? AND WASSHOWN = 0");
stmt.setString(1, serviceInfo.getTicketName());
stmt.executeUpdate();
stmt.close();
}
}
});
}
}
@Override
public UserSettings getUserSettings(String SystemUser) {
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
ReturningWork<UserSettings> returningWork = new ReturningWork<UserSettings>() {
@Override
public UserSettings execute(Connection conn) throws SQLException {
// Read data from database
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM DBO.USER_PROPERTIES");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
// Search if the User exists in the database
if (rs.getString("SYSTEMUSER").equals(SystemUser)) {
// Users exists
return new UserSettings(SystemUser, true, rs.getBoolean("ALLOWNOTIFICATION"),
getUserSystems(SystemUser));
}
}
stmt.close();
return new UserSettings(SystemUser, false, false, getUserSystems(SystemUser));
}
};
return session.doReturningWork(returningWork);
}
}
@Override
public UserSettings createNewUser(String SystemUser) {
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
ReturningWork<UserSettings> returningWork = new ReturningWork<UserSettings>() {
@Override
public UserSettings execute(Connection conn) throws SQLException {
PreparedStatement statement = conn.prepareStatement(
"INSERT INTO DBO.USER_PROPERTIES(systemUser, allowNotification) VALUES (?, 0);");
statement.setString(1, SystemUser);
statement.execute();
statement.close();
statement.close();
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM DBO.USER_PROPERTIES");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
if (rs.getString("systemUser").equals(SystemUser)) {
// Get the newly created User
return new UserSettings(SystemUser, true, rs.getBoolean("allowNotification"),
getUserSystems(SystemUser));
}
}
stmt.close();
// If no User was found in the database create a new User
return new UserSettings(SystemUser, false, false, getUserSystems(SystemUser));
}
};
return session.doReturningWork(returningWork);
}
}
@Override
public void UpdateUserInformation(String SystemUser, Boolean allowNotifications, ServiceSystem serviceSystem) {
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
session.doWork(new Work() {
@Override
public void execute(Connection conn) throws SQLException {
if (allowNotifications != null) {
PreparedStatement stmt = conn.prepareStatement(
"UPDATE DBO.USER_PROPERTIES SET ALLOWNOTIFICATION = ? WHERE SYSTEMUSER = ? AND ALLOWNOTIFICATION = ?");
stmt.setBoolean(1, allowNotifications); // Value to set
stmt.setString(2, SystemUser);
stmt.setBoolean(3, !allowNotifications); // Current value
stmt.executeUpdate();
stmt.close();
}
if (serviceSystem != null) {
Database.UpdateSystemUserTable(SystemUser, serviceSystem);
}
// Add more customizable options
}
});
}
}
@Override
public List<ServiceSystem> getUserSystems(String SystemUser) {
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
ReturningWork<List<ServiceSystem>> returningWork = new ReturningWork<List<ServiceSystem>>() {
@Override
public List<ServiceSystem> execute(Connection conn) throws SQLException {
List<ServiceSystem> returnList = new ArrayList<>();
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM DBO.USER_SYSTEMS");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
if (rs.getString("SYSTEMUSER").equals(SystemUser)) {
returnList.add(new ServiceSystem(rs.getString("SYSTEMNAME"),
Database.getCorrectSystem(rs.getString("SYSTEMNAME")), true));
}
}
return returnList;
}
};
return session.doReturningWork(returningWork);
}
}
@Override
public List<ServiceInformation> getPersonalServiceInformations(List<ServiceSystem> userSystemList) {
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
ReturningWork<List<ServiceInformation>> returningWork = new ReturningWork<List<ServiceInformation>>() {
@Override
public List<ServiceInformation> execute(Connection connection) throws SQLException {
List<ServiceInformation> returnList = new ArrayList<>();
// read data from database
PreparedStatement stmt = connection.prepareStatement("SELECT * FROM BCSTASKS_SERVICE");
ResultSet rs = stmt.executeQuery();
// Cycle trough each result
while (rs.next()) {
List<ServiceSystem> ticketSystemList = Database
.getSystemListFromTicket(rs.getString("IFD_PRODUKTBESTANDTEILE"));
for (int i = 0; i < ticketSystemList.size(); i ) {
for (int j = 0; j < userSystemList.size(); j ) {
if (ticketSystemList.get(i).getSystem() == userSystemList.get(j).getSystem()) {
// Create a new ServiceInformation with the name and description
ServiceInformation tempInformation = new ServiceInformation(rs.getString("NAME"),
rs.getString("ATTACHMENTCOMPONENT"), ticketSystemList,
rs.getBoolean("WASSHOWN"));
// Add the ServiceInformation to the list
returnList.add(tempInformation);
}
}
}
}
stmt.close();
return returnList;
}
};
return session.doReturningWork(returningWork);
}
}
}
Inside of my IDE (Eclipse) everything is working fine, but the .jar file
throws the error above.
I know many other people have this problem, but most of them tried to load a file (.xml for example) and I'm trying to implement an interface. I don't know how much this is different.
I would really appreciate if you could help me out. Thanks in advance-
CodePudding user response:
check if your system scoped dependency is included in the jar! You can unpack the jar with any zip tool.
If you want to include it, check the includeSystemScope option of the spring-boot:repackage goal: https://docs.spring.io/spring-boot/docs/1.4.1.RELEASE/maven-plugin/repackage-mojo.html#includeSystemScope
Just an example, so you can see how to add the option. It's added in the pom.xml file of your project.
[...]
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>full.qualified.MainClass</mainClass>
<layout>ZIP</layout>
<classifier>exec</classifier>
<includeSystemScope>true</includeSystemScope>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
[...]
If you don't want to include it you have to add the jar to your classpath while executing the jar:
(Unix style)
java -cp "middleware-0.0.1-SNAPSHOT.jar:C:\Users\mfi\Downloads\LaunchableJar\remote.jar" -Dloader.main=<YOUR_MAINCLASS_HERE> org.springframework.boot.loader.PropertiesLauncher "$@"