I am trying to get access to a folder that is created in the classpath in a Spring boot application. A snippet of the code is below:
ClassLoader classLoader = ClassUtils.getDefaultClassLoader();
URL url = classLoader.getResource("converters");
LOGGER.debug("**************** url: " + url);
File file = new File(url.toURI());
Path path = Paths.get(file.getAbsolutePath());
Arrays.stream(path.toFile().listFiles()).forEach(f -> LOGGER.debug("*******files: " + f.getName()));
if (!path.toFile().isDirectory()) {
throw new IllegalArgumentException(ErrorCode.INVALID_MAPPERS_DIRECTORY.formatMessage(path));
}
The code above runs without any issues when I run it in Intellij and I get the url as below:
file:/C:/Users/user1/projects/my-service/test/build/resources/main/converters
When I run it on Linux inside the application rpm, I get the url value below:
jar:file:/opt/home/libexec/my-service-2.0.0-SNAPSHOT.jar!/BOOT-INF/lib/my-service-api-2.0.0-SNAPSHOT.jar!/converters
Any reason why is the different behavior?
The difference is the packaging.
Your IDE does not package your application to run it, it just uses the file system as this is faster.
When you package your app and deploy all the resources that your ide can access from the file system are now packaged within your spring boot fat jar file. In your case the file is inside the my-service-api-2.0.0-SNAPSHOT.jar which is packaged inside your fat jar.
Problem
I need to be able to have a reference to a folder that a user may create in the classpath of my Spring Boot application.
Solution
The following worked for me:
mapperFilesFolder = resolver.getResources("classpath*:" + mappersLocation + "/.");
Path path = Paths.get(mappersFolder[0].getURI());
Related
I am trying to consume the WSDL file in the spring boot application, WSDL file is placed into the src/main/resource/wsdl/file.wsdl.
Project structure:
Code:
static {
URL url = null;
try {
url = new URL("file:///" + System.getProperty("user.dir") + "/src/main/resources/wsdl/outbound.wsdl");
} catch(IOException e) {
java.util.logging.Logger
.getLogger(OutboundService.class.getName())
.log(java.util.logging.Level.INFO,
"Can not initialize the default wsdl from {0}",
"file:/D:/ERPLOGIC/ERPProjects/JAVA/mavenproject/eclipse-workspace/topconpoc/src/main/resources/wsdl/outbound.wsdl");
}
WSDL_LOCATION = url;
}
It works fine in locally, but when deployed in the AWS server as a war file, it does not work.
What is the proper to refer to the path in the Spring Boot application?
Try this
URL url = Thread.currentThread().getContextClassLoader().getResource("wsdl/outbound.wsdl");
This should work
The file is placed inside the Java resources directory src/main/resource and should be loaded from there in all cases. The reason it's not loading properly when deployed is that file is not in that location once packaged. Use the class to locate the resource file from the packaged Java app. This should work both locally and when deployed. Make sure to replace ClassFileWhereCodeLives with the class the static code block is inside of.
url = ClassFileWhereCodeLives.class.getResource("/wsdl/outbound.wsdl")
I need to get the path of a key file that i have placed in the root folder of my spring application. Everything works as expected when i run it locally. But when i deploy the application to the server i get a FileNotFoundException.
File file = new File("testfile.key");
String path = file.getAbsolutePath();
I have tried placing the file in the resource folder as well.
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
File file = new File(classLoader.getResource("testfile.key").getFile());
Just need to pass the file path to another method (3rd party library) which will read the content.
Any help would be much appreciated.
This should be a resource, placed in the resource folder (if using maven).
You can access it using
this.getClass().getResource("testfile.key");
The root for accessing files can change between environments but the root for resources is a directory that's specified during compilation. For maven driven projects this is:
src/main/resources
How/Where can I set the relative path location for a packaged (jar) Spring Boot jar application?
The following is what works in my IDE (IntelliJ).
I have in my application.properties file the following properties.
converter.output=upload-dir/output/
converter.input=upload-dir
I have a Java class that controls the properties for me.
#Component
#ConfigurationProperties("converter")
public class ConverterProperties {
//getters
//setters
}
I have the following directory structure within the IDE.
src/
target/
upload-dir/
upload-dir/output/
pom.xml
README.txt
However, I am wanting to know where my upload-dir and upload-dir/output folders would be when I generate a jar and run it from a folder? I have tried putting the folder in the same location as the jar
C:\app\app.jar
C:\app\upload-dir\
C:\app\upload-dir\output\
But no dice. I setup the #ConfigurationProperties based on this documentation. https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html, but I can't seem to find anywhere in there were it talks about packaged jar relative paths.
A typical spring boot application displays some of the information you are looking for in the first line at info level (Starting Application {name} on {host} with PID 1234 ({jarpath} started by {user} in {workdir})
Looking at the source code in StartupInfoLogger, it looks like you need to use the ApplicationHome helper class (in package org.springframework.boot) in order to get that absolute path of the JAR file of your running spring boot application.
Here is an example of Java code to retrieve the location of the jar file and the directory containing the jar file. This is then used to create the uploadDir file (assuming it is a subdirectory of the jar directory)
ApplicationHome home = new ApplicationHome(this.getClass());
File jarFile = home.getSource();
File jarDir = home.getDir();
File uploadDir = new File(jarDir, "upload-dir");
You would want to run this from within one of your application classes running in the spring boot app. Looks like it uses the class passed to the constructor of ApplicationHome in order to find the jar which contains that class.
I am creating a Maven web application which stores many policy files in policy folder. My source folder layout looks like :
I tried to set the folder path as policyLocation as shown below:
try {
// InputStream aa =
// Accesscontrol.class.getClass().getResource(aa);
String AbsolutePath = new File("/").getAbsolutePath();
String policyLocation = (new File("."))
.getCanonicalPath() + File.separator + "policy";
System.setProperty(
FileBasedPolicyFinderModule.POLICY_DIR_PROPERTY,
policyLocation);
} catch (IOException e) {
System.err.println("Can not locate policy repository");
}
But this is returning my Eclipse folder. Is there anyway I can get the policy folder that is not inside Resource folder (cause it can't be included inside Resource) in java web application?
Please keep in mind that your application has more than 1 way to run:
from within IDE (Eclipse) where certain things are done automatically for you (like compilation on the fly)
when you build your web application using maven, do you build it as jar, war, or perhaps ear ? Once built, how do you deploy and run it?
Firstly you have to ensure that your build process (maven) includes the policy files in the distributable (e.g. in the war file) in a known location which you can reference. Then you can modify the classpath within the jar or war and to ensure that your policy files are on the classpath.
With such setup all you have to do is to address it as a resource as per this answer
I am trying to use Sqlite on a web page over Java.
I am getting the following error:
java.lang.NoClassDefFoundError: org/sqlite/JDBC
model.DataBase.<init>(DataBase.java:35)
I've tried the two alternatives:
this.conn = new org.sqlite.JDBC().connect("jdbc:sqlite:" + file, new Properties());
this.stm = this.conn.createStatement();
and
Class.forName("org.sqlite.JDBC");
this.conn = DriverManager.getConnection("jdbc:sqlite:" + file);
this.stm = this.conn.createStatement();
I am using Eclipse and I've configured the jar file in the build path, also, when running as a desktop application it works fine.
Just having the sqllite.jar in your build path is not enough. If you are running it as a web application place the jar in the /WEB-INF/lib folder as well.
You can tell eclipse to export that file as well.
I know you said that you've included the jar file in your build path, but if it's not also in the $CLASSPATH of the server you're running under, then you'll end up with this exception. If the Java Classloader can't find the class inside a jar file that it knows about, you'll get NoClassDefFoundError. I suggest checking the classpath.