GUI Builder generates getClass().getResource() for icons, which fails in modular/multi-module projects
- Dominant language
- Java
- Stars
- 3.1k
- Forks
- 935
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 17
Description
### Apache NetBeans version
Apache NetBeans 27
### What happened
When using the NetBeans GUI Builder (Matisse) to set an icon for a component (e.g., JMenuItem), the generated code uses:
new ImageIcon(getClass().getResource("/path/to/icon.png"))
This works in simple monolithic applications, but **fails in modular projects (JPMS) or multi-module Maven/Gradle projects** where the icon resource resides in a different module.
The issue is that `getClass().getResource()` performs a **class-relative resource lookup**, which is subject to module encapsulation rules. If the resource is in another module (even if on the classpath), it returns `null`, causing a `NullPointerException` at runtime.
In contrast, `ClassLoader.getResource()` performs a **classpath-root lookup** and can access resources across module boundaries (if the class loader has visibility), making it more suitable for multi-module environments.
For example, this works:
new ImageIcon(getClass().getClassLoader().getResource("alwaystech/alwaysswing/resources/images/misc_preferences.png"))
Note:
- No leading `/` when using `ClassLoader.getResource()`
- The path is relative to the classpath root
Suggested Improvement:
Please modify the GUI Builder code generator to:
1. Detect if the project is modular or multi-module, OR
2. Provide an option in the IDE settings to prefer `ClassLoader.getResource()` over `getClass().getResource()`
3. Generate code using `getClassLoader().getResource(path)` (without leading `/`) when appropriate
Alternatively, allow users to define a custom resource loading strategy for icons in GUI forms.
This change would improve compatibility with modern Java project structures and avoid runtime resource loading failures.
Steps to Reproduce:
1. Create a multi-module Maven/Gradle project
2. Place an icon (e.g., misc_preferences.png) in resources of module A
3. In module B, use GUI Builder to set the icon for a JMenuItem
4. Run the application → Icon fails to load (NPE or blank)
### Language / Project Type / NetBeans Component
_No response_
### How to reproduce
1. Create a multi-module Maven/Gradle project
2. Place an icon (e.g., misc_preferences.png) in resources of module A
3. In module B, use GUI Builder to set the icon for a JMenuItem
4. Run the application → Icon fails to load (NPE or blank)
### Did this work correctly in an earlier version?
No / Don't know
### Operating System
debian12.5
### JDK
jdk25
### Apache NetBeans packaging
Apache NetBeans binary zip
### Anything else
_No response_
### Are you willing to submit a pull request?
No
Contributor guide
Research direction
Start with the NetBeans GUI Builder (Matisse) code generator and reproduce the icon-loading failure in a multi-module Maven or Gradle project. Compare generated getClass().getResource() usage with the requested ClassLoader.getResource() behavior, then verify the generated form runs successfully when the icon is in another module.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100