flyway sql file is not able to open another file - java

In my Java project, I am using flyway migration (which is working). In one of my migration file, I have to read a svg file from resource folder to save in a table (column). I am using postgres Database. For that operation, I am using pg_read_file() method.
If I provide absolute path to file, it's working. But with relative path, it's not working out.
src
├── main
│ ├── java
│ └── resources
│ ├── local-images
│ │ └──image.svg
│ └── db
│ │ └──migration
│ │ └──V1__populate_table.sql
└── application.properties
application.properties
# https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto-execute-flyway-database-migrations-on-startup
# provides location of the database migrations sql files
spring.flyway.locations=classpath:db/migration
V1__populate_table.sql
INSERT INTO public.image(
image_id, file)
VALUES ('656cc4e8-9e50-1111-1111-303cdc05a058', pg_read_file('resources/local-images/image.svg')::bytea);
Error
SQL State : 58P01
Error Code : 0
Message : ERROR: could not open file "resources/local-images/image.svg" for reading: No such file or directory
I tried putting both .sql and image.svg file in same folder, but still no luck.

Try loading your resources file using the java classloader:
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("local-images/image.svg");
byte[] fileBytes = IOUtils.toByteArray(inputStream);
INSERT INTO public.image (image_id, file)
VALUES ('656cc4e8-9e50-1111-1111-303cdc05a058', bytes::bytea);
EDIT
pg_read_file() reads files from the file system relative to the data directory of the cluster, not the application classpath. To read the file from the resources directory you can:
Provide the absolute path of the file
Provide a path relative to the data directory
You could try copying that file from resources to a location on the file system and then use pg_read_file() to read the file from that location before executing the SQL statement.

Related

How to read multiple property files from a GitHub folder using Spring Cloud?

I have a Spring server that accesses a specific GitHub repo. The repo contains a folder and has multiple property files and all of them have different names, so I can't get them using their corresponding application and profile. Is there any way I can retrieve all of them without needing their name?
For example my spring cloud server currently accesses the application.properties file from my github repo. If there exists another folder and within that folder there exist multiple .properties files how do i retrieve them?
spring:
cloud:
config:
server:
git:
uri : https://github.com/xxxxxx/cloud-config-server.git
management:
endpoints:
web:
exposure:
include: "*"
FOLDER
│ ├── example1.properties
│ └── example2.properties
│ ├── example3.properties
│ └── example4.properties
Can I access all of these property files from this folder in one shot, without any specific need for their names?

macOS dynamic linker reports it loaded library which doesn't exist

When running java with DYLD_PRINT_LIBRARIES=TRUE the following lines are contained in the output:
dyld[15078]: <C77B7FE3-7104-362A-B686-168971378ADC> /System/Library/Frameworks/JavaNativeFoundation.framework/Versions/A/JavaNativeFoundation
dyld[15078]: <BE429D77-6080-3D27-B4EE-12EE022386B4> /System/Library/Frameworks/JavaRuntimeSupport.framework/Versions/A/JavaRuntimeSupport
However the repsecitve folders don't actually contain any binary files to load. For example this is the directory structure of JavaNativeFoundation.framework:
/System/Library/Frameworks/JavaNativeFoundation.framework
├── Resources -> Versions/Current/Resources
└── Versions
├── A
│ ├── Resources
│ │ ├── BridgeSupport
│ │ │ └── JavaNativeFoundation.bridgesupport
│ │ ├── Info.plist
│ │ └── version.plist
│ └── _CodeSignature
│ └── CodeResources
└── Current -> A
7 directories, 4 files
Loading a dynamic library which links against the framework JavaNativeFoundation in the java program fails as expected:
java.lang.UnsatisfiedLinkError: <path to the library>: dlopen(<path to the library>, 0x0001): Library not loaded: #rpath/JavaNativeFoundation
Referenced from: <path to the library>
Reason: tried:
'/System/Library/Frameworks/JavaNativeFoundation.framework/Versions/Current/JavaNativeFoundation' (no such file),
'/System/Library/Frameworks/JavaNativeFoundation.framework/Versions/Current/JavaNativeFoundation' (no such file),
'/Library/Java/JavaVirtualMachines/jdk8u232-b09/Contents/Home/jre/lib/server/./JavaNativeFoundation' (no such file),
'/Library/Java/JavaVirtualMachines/jdk8u232-b09/Contents/Home/jre/lib/server/../JavaNativeFoundation' (no such file),
'/Library/Java/JavaVirtualMachines/jdk8u232-b09/Contents/Home/bin
Note that /System/Library/Frameworks/JavaNativeFoundation.framework/Versions/Current/ is a symlink to /System/Library/Frameworks/JavaNativeFoundation.framework/Versions/A/ so both logs actually refer to the same file. For me this looks like a contradiction. How can the dynamic linker load and not load
/System/Library/Frameworks/JavaNativeFoundation.framework/Versions/[Current/A]/JavaNativeFoundation at the same time.
I don't believe this to be specific to Java at all. It's just the context in which this pops up.
Some information regarding the OS (all mentioned machines are Intel x86-64 based):
The above scenario is for macOS 12.1
The binary for JavaNativeFoundation is also missing on macOS 11.5.2
On a different machine running 10.15.7 it exists.
This is due to:
New in macOS Big Sur 11 beta, the system ships with a built-in dynamic linker cache of all system-provided libraries. As part of this change, copies of dynamic libraries are no longer present on the filesystem. Code that attempts to check for dynamic library presence by looking for a file at a path or enumerating a directory will fail. Instead, check for library presence by attempting to dlopen() the path, which will correctly check for the library in the cache.
Apparently this also affects the dynamic linker itself while resolving transitive dependencies of a library. If the load command contains an absolute path it resolves it correctly. It’s only in the case that the path contains #rpath entries that the linker will check for the existence of the path (after substitution) and ignored the linker cache.

Issue while picking file from main/resource folder of maven folder structure

I am trying to fetch a file from src/main/resources folder.
Earlier it was working fine but recently it has started picking that file from some target location (target/classes/filename.xml) (I did not create that file in target folder).
File xmlFile = new File(ReadXMLFile.class.getClassLoader().getResource(“filename.xml”).toURI());
Code that I am trying is:
File xmlFile = new File(ReadXMLFile.class.getClassLoader().getResource(“filename.xml”).toURI());
Expected: it should pick the file from src/main/resources/filename.xml
actual: it is picking the file from target/classes/filename.xml
Additional Info: My code is in ReadXMLFile.xml and its under the below folder structure
com.qa.smartcomm.util
ReadXMLFile.xml
Can someone help me with this issue?
Make sure you have structure(Module) like below:
├── src
│ └── main
│ ├── java
│ │ └── somepackage
│ │ └──Main.java
│ │
│ │
│ │
│ └── resources
│ └── filename.xml
└── pom.xml
File xmlFile = new File(String.valueOf(getClass().getClassLoader().getResourceAsStream("filename.xml")));
Target Folder is automatically by maven. It copies the resources from src/main/resources to target/classes/ together with the compiled java classes from src/main/java.
If you run your program target/classes is the root of you classloader.

Open a file from the src directory (Java)

I've written a short documentation for my Java program. When clicking on the menu Help -> Documentation the default PDF reader of the OS should open the documentation.pdf.
I'm trying to open the PDF which is located in the directory src/doc with Desktop.getDesktop().open(new File("doc/documentation.pdf")); in Controller.java.
However, Java does not find the file. When I open the icon for the program with primaryStage.getIcons().add(new Image("icon/icon_512x512.png")); it works perfectly in Main.java.
Here you can see layout of my IntelliJ project.
src
├── META-INF
├── de
│   └── myapp
│   ├── model
│ │ └── *.java
│   ├── view
│ │ └── *.java
│ ├── Main.java
│   └── Controller.java
├── doc
│ └── documentation.pdf
└── icon
└── icon_512x512.png
My stack
IntelliJ 2016.2
Java 1.8.0_77
It works with new Image("icon/icon_512x512.png") because internally it gets is from the context ClassLoader which is not the case of new File("doc/documentation.pdf") that gets it from the user working directory in case of a relative path, so you could simply apply the same logic.
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
URL resource = contextClassLoader.getResource("doc/documentation.pdf");
Desktop.getDesktop().open(new File(resource.toURI()));
3-rd party applications can not access src dir in your application, in case, when your app assemble in jar archive. You should place your file separately from src.
Of course, java find icons, because it's java API.
You can access any resources in src folder through follow methods:
URL url = getClass().getResource("/path/in/src");
InputStream is = getClass().getResourceAsStream("/path/in/src");
If your app is NOT assemble in JAR - try provide full path to file like this:
URL url = getClass().getResource("/path/in/src");
File file = new File(url.toURI());
The files from Classpath can be loaded by using ClassLoader's getResourceAsStream Method.
So you can try with generating an Input stream object
InputStream is = Controller.class.getClassLoader().getResourceAsStream("doc/documentation.pdf");
And After generating Input Stream you can read it by Java Program.

Java jar can't access resources

I need to execute a jar file which uses some files located in some subfolders.
For example the directory tree can be like this:
jar_root/
├── executable.jar
├── folder1/
│ └── required_file1.txt
│
├── folder2/
│ └── required_file2.txt
│
├── other_folder/
│ └── ...
└── other_file.txt
In this example executable.jar needs to access required_file1 and required_file2.
I need to execute the jar from another directory, so I tried this command:
java -cp /path/to/jar_root/ -jar /path/to/jar_root/executable.jar <options>
But what I got is a FileNotFoundException on required_file1 (I guess the same Exception will be raised for required_file2)
How can I make the jar work?
Note that I cannot modify the jar, so I can't use getResourceAsStream, as suggested by this (and other) answer(s).
It depends on how the code in the jar tries to access the files. If by relative path, that can only work if you start the program from the appropriate working directory, for example:
cd /path/to/jar_root/
java -jar executable.jar <options>
An alternative is to reference the files by absolute path, or relative from classpath instead of filesystem path.

Categories