Vaadin-maven-plugin "java.lang.ClassNotFoundException"

Hi, I am having an exception in the “vaadin-maven-plugin”. I made a configuration in order to use a custom Jackson object mapper that works fine when I run the project from IDE, but it is causing a “java.lang.ClassNotFoundException” when I try to generate the production package.

This is the plugin configuration with the jackson mapper:

 			<plugin>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-maven-plugin</artifactId>
                <version>${vaadin.version}</version>
                <configuration>
				    <parser>
				        <plugins>
							<disableAllDefaults>true</disableAllDefaults>
				        	<use>
				                <plugin>
				                    <name>com.vaadin.hilla.parser.plugins.backbone.BackbonePlugin</name>
				                    <configuration implementation="com.vaadin.hilla.parser.plugins.backbone.BackbonePluginConfiguration">
				                    	<objectMapperFactoryClassName>com.example.MyObjectMapperFactory</objectMapperFactoryClassName>
				                    </configuration>
				                </plugin>
				                <plugin>
				                    <name>com.vaadin.hilla.parser.plugins.transfertypes.TransferTypesPlugin</name>
								</plugin>
				                <plugin>
				                    <name>com.vaadin.hilla.parser.plugins.nonnull.NonnullPlugin</name>
								</plugin>
				                <plugin>
				                    <name>com.vaadin.hilla.parser.plugins.subtypes.SubTypesPlugin</name>
								</plugin>
				                <plugin>
				                    <name>com.vaadin.hilla.parser.plugins.model.ModelPlugin</name>
								</plugin>					
							</use>
				        </plugins>
				    </parser>
			    </configuration>
            </plugin
$ ./mvnw -X -Pproduction clean compile com.vaadin:vaadin-maven-plugin:24.4.6:build-frontend
Caused by: java.lang.ClassNotFoundException: com.example.MyObjectMapperFactory
    at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass (SelfFirstStrategy.java:50)
    at org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass (ClassRealm.java:271)
    at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass (ClassRealm.java:247)
    at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass (ClassRealm.java:239)

I cannot figure out how to solve the ClassNotFoundException, any idea is really appreciated.

Thanks,
Ed

Is com.example.MyObjectMapperFactory a class in your project? If so, most likely it is not seen by the plugin classloader

Yes, its a class in the project compiled in ./target/classes directory. I think the same, the pluggin is not seeing those clases. What are my options? Is there any parameter I can add in pom.xml or in the command line to pass the path to the comiled class or something similar so the pluggin can load it?

Only thing that comes in mind at the moment, is to put the class in a separate module and add the artifact to the plugin definition dependencies

Thank you for your comments. Do you mean creating a new maven dependency/artifac with the MyObjectMapperFactory inside? I wonder now if there is a maven pluggin that allows me to run the vaadin-maven-plugin with an altered classpath. :/

Yes, I mean create a new independent maven module/project with the customized class.

I’m not aware of any workaround to augment the plugin class loader by configuring the POM file, other than adding entries in the <dependencies> section of the plugin configuration.

1 Like

Marco is right that’s the correct way

1 Like

Yes, that will work. However, because chances of modiffing the mapper are high I ended up modifing the mojo build pluggin so I added a “includeInRealmPaths” property so I can add extra paths to the ClassRealm. Here is the code in case helps anybody.

    @Parameter(property = "includeInRealmPaths")
    private List<String> includeInRealmPaths;
    
    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
        getLog().debug("Starting execution of mojo BuildFrontendMojo");
            final PluginDescriptor pluginDescriptor = (PluginDescriptor) getPluginContext().get("pluginDescriptor");
            if (includeInRealmPaths != null && !includeInRealmPaths.isEmpty()) {
                getLog().debug("Inclusions in realm detected");
                for (String path : includeInRealmPaths) {
                    getLog().debug("Including '" + path + "'");
                    final ClassRealm classRealm = pluginDescriptor.getClassRealm();
                    try {
                        classRealm.addURL(new File(path).toURI().toURL());
                    } catch (MalformedURLException e) {
                        getLog().error("I could not include in realm" + e);
                        e.printStackTrace();
                    }
                }
            } else {
                getLog().debug("No inclusions in realm requested");
            }
        super.execute();
    }
}

And I use that new config as follows

<configuration>
   <includeInRealmPaths>
      <includeInRealmPath>./target/classes/</includeInRealmPath>
   </includeInRealmPaths>
...
</configuration>

It’s working fine so far, and also I am satified avoid creating an new artifact just for a single class.

Thanks for your comments and support mates.

Good work!
Do you mind creating a feature request issue on the Hilla repository explaining the problem and posting your solution?
Hilla team may be interested in improving the official plugin.