# ClassNotFound Exception when Registering Reporting Component

**URL:** <https://forum.inductiveautomation.com/t/classnotfound-exception-when-registering-reporting-component/78826>\
**Category:** Module Development\
**Tags:** ignition81\
**Created:** [September 6, 2023, 5:17pm UTC](https://forum.inductiveautomation.com/t/classnotfound-exception-when-registering-reporting-component/78826 "2023-09-06T17:17:40Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![cody.tamaki](https://avatars.discourse-cdn.com/v4/letter/c/b487fb/32.png) [@cody.tamaki](https://forum.inductiveautomation.com/u/cody.tamaki)\
**Post date:** [September 6, 2023, 5:17pm UTC](https://forum.inductiveautomation.com/t/classnotfound-exception-when-registering-reporting-component/78826/1 "2023-09-06T17:17:40Z")

</div>

I'm trying to register a new reporting component that I've built, and the GatewayHook class loader doesn't seem to be able to find the "AbstractJ2DShape" class. Do I need to force it to use a specific class loader?

I'm using the following dependency in my common pom.xml:

```auto
        <dependency>
            <groupId>com.inductiveautomation.ignitionsdk</groupId>
            <artifactId>reporting-common</artifactId>
            <version>8.1.14</version>
            <type>pom</type>
            <scope>provided</scope>
        </dependency>

```

The exception I'm getting is:

```auto
java.lang.NoClassDefFoundError: com/inductiveautomation/rm/shape/j2dshapes/AbstractJ2DShape
.........................
Caused by: java.lang.ClassNotFoundException: com.inductiveautomation.rm.shape.j2dshapes.AbstractJ2DShape
at java.base/java.net.URLClassLoader.findClass(Unknown Source)
at com.inductiveautomation.ignition.gateway.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:37)
at com.inductiveautomation.ignition.gateway.modules.ModuleClassLoader.loadClass(ModuleClassLoader.java:104)
at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
... 26 common frames omitted

```

I've run `mvn clean install` and restarted my Gateway just in case that's the problem...

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [September 6, 2023, 5:18pm UTC](https://forum.inductiveautomation.com/t/classnotfound-exception-when-registering-reporting-component/78826/2 "2023-09-06T17:18:51Z")

</div>

Is your module itself marked as depending on the reporting module, in the `module.xml`?

---

<div class="post-metadata">

**Author:** ![cody.tamaki](https://avatars.discourse-cdn.com/v4/letter/c/b487fb/32.png) [@cody.tamaki](https://forum.inductiveautomation.com/u/cody.tamaki)\
**Post date:** [September 6, 2023, 5:26pm UTC](https://forum.inductiveautomation.com/t/classnotfound-exception-when-registering-reporting-component/78826/3 "2023-09-06T17:26:40Z")

</div>

That was it... I knew it was going to be something simple like that.

I do have a related question though - if I don't want my module to depend on the reporting module, is there a way I can configure that? So for instance, my module is mostly providing a back-end service on the gateway and I'm creating a few perspective/reporting components as additional "bonus" features. I don't want the module installation to fail if the end user doesn't have Reporting or Perspective installed just for these "niceties", I'd rather just add a try/catch somewhere, log a warning and move on.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [September 6, 2023, 5:35pm UTC](https://forum.inductiveautomation.com/t/classnotfound-exception-when-registering-reporting-component/78826/4 "2023-09-06T17:35:57Z")

</div>

Module dependencies are "soft", it will log a warning but load your module anyway.

You do need to place a conditional guard around your code that loads/accesses classes from the report module, though. Something like:

```auto
if (context.getModuleManager().getModule("reporting-module-id") != null) {
  // .. do stuff to register your component here.. 
}

```

might be enough. If not you'll have to do some reflection trickery.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [September 6, 2023, 6:27pm UTC](https://forum.inductiveautomation.com/t/classnotfound-exception-when-registering-reporting-component/78826/5 "2023-09-06T18:27:41Z")

</div>

> [@Kevin.Herron](#):
>
> If not you'll have to do some reflection trickery.

The trickery is usually factoring out the reporting-specific initialization (or anything in the lifecycle) into a separate class, so that the gateway hook itself doesn't have any binary reference to the reporting module or to that separate class file. Where needed, you load that special class by name and skip if it fails.

Same idea for Perspective or any other soft dependency.
