netbeans icon indicating copy to clipboard operation
netbeans copied to clipboard

GUI Builder generates getClass().getResource() for icons, which fails in modular/multi-module projects

Open hellas2000 opened this issue 2 months ago • 1 comments

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

hellas2000 avatar Oct 13 '25 02:10 hellas2000

thanks for investigating! I think it would be good to generate code which works in both situations (if possible), so that it remains portable. But probing for module-info.java and making a decision based on that could be probably also done.

mbien avatar Nov 12 '25 16:11 mbien