Environment: Eclipse, OpenJDK12, Maven, modular project.
My project structure:
src
\main
| \java
| \com
| | \myApp
| | | \otherFolders
| | | \controllers
| | | |--ToolBar.java
| | |--MainApp.java
| |--module-info.java
src
\main
\resources
\com
\myApp
|--ToolBar.fxml
|--MainApp.fxml
\--controllers
|--logo.png
Context:
I'm trying to load the image located in /src/main/resources/com/myApp/controllers
from outside Eclipse, after use jlink for build and export. It is in the same module, not an external folder, not a different module.
My resources folder structure match the package folder structure. I don't want to put all resources in the root resources folder or in a new package with the java classes. I want to maintain this structure, is this possible?
Error:
I'm always getting a: java.lang.NullPointerException: Input stream must not be null
when runing the app outside Eclipse.
Research:
I already read most of threads regarding this and I would prefer to not post all the code references as it would be a mess to write the question.
These links are the most near to what I'm asking but couldn't make it work:
Resource from src/main/resources not found after building with maven
How to access resource using class loader in Java 9
Java 9 Module system Resources files location
Making the folder structure leading to your resource match a suitable package in your project.
I already have this
Loading classes and resources in Java 9:
non-class-file resources in a module are encapsulated by default, and hence cannot be located from outside the module unless their effective package is open
My package is open to the class which needs access the resource
Code:
Controller
package com.myApp.controllers;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
public class ToolBar implements Initializable {
@FXML
private ImageView imageViewLogo;
public ToolBar () {
}
@Override
public void initialize(URL location, ResourceBundle resources) {
Image img = null;
try {
// inside eclipse ok - outside fail
img = new Image(ToolBar .class.getResourceAsStream("logo.png"));
System.out.println("Attemp 1:" + img.toString());
} catch (Exception e) { e.printStackTrace();}
try {
// inside eclipse ok - outside fail
img = new Image(ToolBar .class.getResource("logo.png").toExternalForm());
System.out.println("Attemp 2:" + img.toString());
} catch (Exception e) { e.printStackTrace();}
try {
// inside eclipse fail - outside fail
img = new Image(ToolBar.class.getClassLoader().getResource("logo.png").toExternalForm());
System.out.println("Attemp 3:" + img.toString());
} catch (Exception e) { e.printStackTrace();}
try {
// inside eclipse fail - outside fail
img = new Image(getClass().getResourceAsStream("/com/myApp/controllers/logo.png"));
System.out.println("Attemp 4:" + img.toString());
} catch (Exception e) { e.printStackTrace();}
imageViewLogo.setImage(img);
}
}
module-info.java
module myApp {
requires javafx.controls;
requires javafx.fxml;
requires transitive javafx.graphics;
requires javafx.base;
requires java.desktop;
opens com.myApp.controllers to javafx.fxml, javafx.scene.image.Image;
exports com.myApp;
}
pom
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.myApp</groupId>
<artifactId>myApplicattion</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>12</maven.compiler.source>
<maven.compiler.target>12</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>12.0.1</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>12.0.1</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>12.0.1</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-base</artifactId>
<version>12.0.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>12</release>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.3</version>
<configuration>
<release>12</release>
<stripDebug>true</stripDebug>
<compress>2</compress>
<noHeaderFiles>true</noHeaderFiles>
<noManPages>true</noManPages>
<launcher>myApplicattionLauncher</launcher>
<jlinkImageName>myApplicattionFX</jlinkImageName>
<jlinkZipName>myApplicattionZIP</jlinkZipName>
<mainClass>com.myApp.MainApp</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
Update
Before trying to do this programatically, I was loading the image from the fxml as follows and it worked fine. Why?
<ImageView...>
<Image url="@../controllers/logo.png" />
</ImageView>
Update 2
Compiled structure:
com
| \myApp
| \controllers
| | |--ToolBar.class
| | |--logo.png
| |--MainApp.class
|--module-info.class
I don't know what else to do. Is there any good documentation for this? Any help appreciated.