Docker image build with maven doesn't see static files - java

I have a simple Java backend build with Maven. When I create .jar file with mvn clean install, I can run it and everything works fine.
However, when I deploy it to Docker, the server runs, but when I make a GET call, the backend doesn't see static .png file located in src/main/resousces/.
java.io.FileNotFoundException: /src/main/resources/logo.png (No such file or directory)
The image is uploaded to docker with this .gitlab-ci.yml file:
services:
- docker:dind
before_script:
- docker info
maven-build:
stage: build
tags:
- maven3-jdk11
except:
- tags
script:
- mvn deploy -B -U
maven-release:
stage: deploy
tags:
- maven3-jdk11
only:
- tags
script:
- mvn deploy -B -Prelease-profile -Dmaven.javadoc.failOnError=false
(This is my first time working with Maven and Docker, so if the information I provided is not sufficient, please leave a comment.)

Okay, I managed to solve it using java ClassLoader.
Originally, I loaded the .png file like this:
Image logo = new Image(ImageDataFactory.create("src/main/resources/logo.png"));
I changed that to following and now it works like charm:
ClassLoader classLoader = getClass().getClassLoader();
Image logo = new Image(ImageDataFactory.create(classLoader.getResource("logo.png")));
I accepted Eugene's answer to boost his reputation, he moved me in the right direction.

Unpack your jar file and check if .png file in it. If not, you need to package a jar with the resources folder. If yes, so you need to specify the path to file using classpath.

Related

Java Cloud Run Won't find file in resources folder

My Java Springboot cloud run instance finds the files in my resources directory locally when I use
mvn clean spring-boot:run
but when I try to deploy to a cloud run instance it doesn't find the file. What's going on? Google's documentation is completely lacking and the examples don't cover this case. Not sure what's happening.
Obviously, the directory works because I have an application.properties file that's being read.
Folder structure
src
--main
----code
--resources
----application.properties
----kafka.properties
I also ran a func that traces the output of all the files in the dir for default "/" folder when trying to use a file and it just lists
myapp.jar
bin
dev
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
so I think it's pointing to the wrong folder but I'm not sure why or how to change it.

Pack node.js files inside fatJar

I have a Spring boot project that also executes a node.js file at one point. My project structure is:
ROOT
- src/
- jsModules/
- script.js
At one point, I execute the script.js (with some parameters) from the java code using:
Process proc = Runtime.getRuntime().exec(executingScriptString);
Once I pack that into a fatJar i have to manually copy-paste the jsModules folder and the script.js to be in the folder root where the .jar is.
Is it maybe somehow possible to pack all the JS files into the fatJar so once I pack it up, I don't need to worry about JS files being copied.
I tried searching how to do this but didn't come across any answers.
Here is the answer:
Place the JS file inside the resources folder which makes it available on the classpath.
When executing the script make sure to adjust the path of the file. In my case it would be:
node src/main/resources/script.js.
Instead of the "/" symbol I'm using File.separator from java.io package and seems to be working correctly although on Windows it creates a string of node src\main\resources\pptrSoccer.js.
Hope it helps someone.
EDIT:
I tried using ResourceLoader (from Spring framework)
resourceLoader.getResource("classpath:script.js").getFile().getAbsolutePath();
It works while it's exploded (running from IDE) but when I pack to a fatJar it doesn't work.

Travis CI doesn't deploy to Azure from GitHub the war file correctly

My problem is that the packaged war file is not deployed from GitHub to Azure using Travis-CI correctly - the entire repository with the generated files are just copy-pasted. Here is what I do:
My approach:
I follow the Travis tutorial about Azure web app deployment and try to achieve the same in the minimal form. My goal is to assemble a war file and deploy it to Azure web app with Tomcat 8.0 container.
My project has the following .travis.yml configuration (I have omitted Java-8 definition, Sonar add-ons, and Coveralls after_success script for the sake of brevity):
script:
- mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent package sonar:sonar
deploy:
provider: azure_web_apps
skip_cleanup: true
I use AZURE_WA_USERNAME, AZURE_WA_PASSWORD and AZURE_WA_SITE environment variables.
I follow the standard Maven directory structure. The output directory is the standard /target. Thus, on the Travis is generated into:
/home/travis/build/MY_USERNAME/MY_WEBAPP/target/MY_WEBAPP.war
Where MY_USERNAME is the GitHub login name and MY_WEBAPP is the name of my application. The deployment looks fine at the first sight (I skipped similar lines):
Deploying application
[detached HEAD 9fd0ce7] Skip Cleanup Commit
54 files changed, 128 insertions(+)
create mode 100644 target/MY_WEBAPP-0.0.1-SNAPSHOT.war
create mode 100644 target/MY_WEBAPP-0.0.1-SNAPSHOT.war.original
create mode 100644 target/MY_WEBAPP-0.0.1-SNAPSHOT/WEB-INF/classes/... <- Skipped 3 lines
create mode 100644 target/MY_WEBAPP-0.0.1-SNAPSHOT/WEB-INF/lib/... <- Skipped 20+ lines
... irrelevant ... <- Skipped 7 lines
Done. Your build exited with 0.
What is wrong and how it should be correct:
If I upload manually the war file via FTP(S) to the Azure directory /site/wwwroot/webapps, it's unpacked and deployed within a minute and works well.
Unlike the manual copy, Travis takes all the content and copy-paste it literally into the Azure webapp resulting in the mess like:
The war file hasn't been uploaded into the webapps folder. The newly created Azure webapp contains site/wwwroot/webapps/ROOT folder and is needed to upload the war file on the ROOT folder level. I have expected Travis would perform "smarter" behavior.
Question:
How to deploy to Azure from GitHub using Travis-CI correctly? I bet I miss something that isn't documented.
My workaround-attempts:
I have tried to fix the thing in several ways (none of them has worked). I consider all of them dirty:
I tried to specify what to deploy in .travis.yml (no effect, everything is copied still):
file_glob: true
file: "/home/travis/build/MY_USERNAME/MY_WEBAPP/target/MY_WEBAPP*.war"
An ugly bruteforce: Change the output directory from /target to /webapp resultin to override the destination folder in Azure upon deployment in the <build> section of 'pom.xml`:
<directory>/webapps</directory>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warName>MY_WEBAPP</warName>
<outputDirectory>/webapps</outputDirectory>
</configuration>
</plugin>
Rename the output folder to webapps in .travis.yml:
after_success:
- bash mv /home/travis/build/MY_USERNAME/MY_WEBAPP/target/ /home/travis/build/MY_USERNAME/MY_WEBAPP/webapps/
/bin/mv: /bin/mv: cannot execute binary file
I have resolved the issue with uploading deployment scripts:
.deployment
[config]
command=deployment.cmd
deployment.cmd
#echo off
echo Azure: Deploying site
echo Azure: Removing the current war file
del %DEPLOYMENT_TARGET%\webapps\MY_WEBAPP.war /S /Q
echo Azure: Removing the current webapp folder
rmdir %DEPLOYMENT_TARGET%\webapps\MY_WEBAPP /S /Q
echo Azure: Copying war to the webapps folder
xcopy %DEPLOYMENT_TARGET%\..\repository\target\MY_WEBAPP.war %DEPLOYMENT_TARGET%\webapps /Y /s

java command not found in terminal

I am trying to use deck2pdf which is a java program to make pdf out of javascript slides presentation.
I followed the installation process from github:
cloned the repo
made ./gradlew distZip which generated a .zip file in build/distributions/
unizpped this file deck2pdf-0.2-SNAPSHOT.zip in my JS project folder
this folder has the following content:
- deck2pdf-0.2-SNAPSHOT
- bin
- deck2pdf
- deck2pdf.bat
- lib
- deck2pdf-0.2-SNAPSHOT.jar
- groovy-2.3.2.jar
- itextpdf-5.5.1.jar
- jfxrt.jar
then, I call deck2pdf in the terminal from my project folder,
but it says : command not found
what am I doing wrong?
Instead of:
deck2pdf
You need to run
./deck2pdf

How to add path to resource directory to an executable jar

I am trying to create an executable jar (code.jar) that depends on another jar file (other.jar) that I create in a separate project(=directory).
The problem I'm having is that there is a class in other.jar that looks for an image file (xyz.gif) that is contained within that project:
e.g., project 'other' looks like: build/ images/xyz.gif src/... etc.
I make other.jar (including the /images directory) and then I make code.jar.
However, when I run
java -jar code.jar - it is unable to locate xyz.gif:
java.lang.IllegalArgumentException: input == null!
at javax.imageio.ImageIO.read(ImageIO.java...)
I have tried everything I can think of to communicate the path to images/xyz.gif to the jar, including:
1. I tried adding the CLASS-PATH: images/ to the MANIFEST.MF for other.jar
2. I tried copying the images directory into the build for code.jar and adding CLASS-PATH: images/ to the MANIFEST.MF for code.jar
3. I tried putting CLASS-PATH: images/xyz.gif - in both manifest files
This seems like a general problem: How to include a (non-class) resource (e.g., an image file) to a java jar file in
such a way that java can locate it (without subsequent packages that utilize the sub-package - e.g., code.jar uses other.jar)
needing to know the details.
Say I can successfullly run the code project using:
java -cp somepath/images com.xyz.code
What I want to do is run:
java -jar code.jar - and have it locate the images/ directory on the classpath.
I should add that the image-containing jar (other.jar) project is not my code - I am just trying to compile it to use. That code tries to load the image using:
javax.imageio.ImageIO.read(ClassLoader.getSystemResource("xyz.gif");
There seems to be a lot of discussion about whether this is the correct/best way to load an image - I assume that the authors of this code DID have it working using Eclipse (whi
ch likely sorted out the paths), and I simply want to get it working on the command line (and eventually in ant).
Any help would be greatly appreciated. I don't understand why the documentation on jar creation is so minimal.
Instead of running jar directly try putting it in classpath. Something like this:
java -cp code.jar MainClass
This might work.
EDIT:
Above solution will not work. Try the below code to get image.
ImageIcon myIcon = new ImageIcon( this.getClass().getResource("/resources/icon.gif"));
and place the image at below locations:
/myApp/src/resources/icon.gif
/myApp/bin/resources/icon.gif

Categories