I want to use Netbeans' Swing GUI builder together with a Maven project and java modules. It seems like the GUI Builder can not find the compiled classes if they are compiled as part of a java module. It gives the error "Error in loading component (...) Cannot load component class (...)" (See the whole error in the screenshot at the end of the example)
I have pinned it down to a minimal example, using Netbeans 11:
File > New Project > Java with Maven > Java Application (use default suggestions and click Finish)
In the project tree under "Source Packages", right click and add a new JFrame, and a JPanel.
Compile the project (Run > Build project), so that you can use the classes with GUI Builder
Using the GUI Builder, add an instance of the JPanel to the JFrame, by opening the JFrame in design mode, and dragging the JPanel to the JFrame.
Update the project to using java modules, by adding the file
src/main/java/module-info.java
:
module MavenGuiTest {
requires java.desktop;
requires java.logging;
}
Run "Build project" again. Netbeans then detects that it is now a java module project and shows a dialog:
Click Yes, and the following will be added to pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
</plugin>
</plugins>
</build>
Run "Build project" again. Now the project is compiled.
Close the JFrame if it's open in the editor.
- Open it again, and switch to the "Design" tab.
- Now, you get an error:
When clicking Show Exceptions, you can see that the GUI Builder cannot find the compiled class of the JPanel:
Here is the full exception text:
java.lang.ClassNotFoundException: com.mycompany.mavenproject1.NewJPanel
at org.netbeans.modules.form.project.ProjectClassLoader.findClass(ProjectClassLoader.java:163)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at org.netbeans.modules.form.project.FormClassLoader.findClass(FormClassLoader.java:58)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:398)
at org.netbeans.modules.form.project.ClassPathUtils.loadClass(ClassPathUtils.java:89)
at org.netbeans.modules.form.FormUtils.loadClass(FormUtils.java:1552)
at org.netbeans.modules.form.PersistenceObjectRegistry.loadClass(PersistenceObjectRegistry.java:73)
at org.netbeans.modules.form.GandalfPersistenceManager.restoreComponent(GandalfPersistenceManager.java:673)
at org.netbeans.modules.form.GandalfPersistenceManager.loadComponent(GandalfPersistenceManager.java:949)
at org.netbeans.modules.form.GandalfPersistenceManager.loadForm(GandalfPersistenceManager.java:484)
at org.netbeans.modules.form.GandalfPersistenceManager.loadForm(GandalfPersistenceManager.java:260)
at org.netbeans.modules.form.FormEditor$2.run(FormEditor.java:327)
at org.netbeans.modules.form.FormLAF$2.run(FormLAF.java:268)
at org.netbeans.modules.openide.util.NbMutexEventProvider$Event.doEventAccess(NbMutexEventProvider.java:115)
at org.netbeans.modules.openide.util.NbMutexEventProvider$Event.readAccess(NbMutexEventProvider.java:75)
at org.netbeans.modules.openide.util.LazyMutexImplementation.readAccess(LazyMutexImplementation.java:71)
at org.openide.util.Mutex.readAccess(Mutex.java:225)
at org.netbeans.modules.form.FormLAF.executeWithLookAndFeel(FormLAF.java:251)
at org.netbeans.modules.form.FormEditor.loadFormData(FormEditor.java:324)
at org.netbeans.modules.nbform.FormEditorSupport.loadOpeningForm(FormEditorSupport.java:436)
at org.netbeans.modules.nbform.FormDesignerTC.loadForm(FormDesignerTC.java:256)
at org.netbeans.modules.nbform.FormDesignerTC.access$300(FormDesignerTC.java:64)
at org.netbeans.modules.nbform.FormDesignerTC$PreLoadTask$1.run(FormDesignerTC.java:245)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
at org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:136)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
I cannot figure out how to fix it, and I have not found any workaround.
org.netbeans.modules.form.project.ProjectClassLoader.findClass(ProjectClassLoader.java:163)
– SubOptimal