# Include third party dependencies in Ignition module

**URL:** <https://forum.inductiveautomation.com/t/include-third-party-dependencies-in-ignition-module/82838>\
**Category:** Ignition\
**Created:** [December 7, 2023, 1:34pm UTC](https://forum.inductiveautomation.com/t/include-third-party-dependencies-in-ignition-module/82838 "2023-12-07T13:34:53Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![BenS](https://avatars.discourse-cdn.com/v4/letter/b/9fc348/32.png) [@BenS](https://forum.inductiveautomation.com/u/BenS)\
**Post date:** [December 7, 2023, 1:34pm UTC](https://forum.inductiveautomation.com/t/include-third-party-dependencies-in-ignition-module/82838/1 "2023-12-07T13:34:53Z")

</div>

I am trying to build an Ignition SDK module that integrates Ignition with third party Java dependencies that are on my local computer. I am following the Gradle example that was used in the Ignition SDK course on Inductive University. My module successfully builds and installs; however, when I test the module by running a command in the Execute console in Designer, I get an error that the dependencies are not found. How would I include these with my module?

---

<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:** [December 7, 2023, 2:02pm UTC](https://forum.inductiveautomation.com/t/include-third-party-dependencies-in-ignition-module/82838/2 "2023-12-07T14:02:42Z")

</div>

Can you share your gradle build file?

Have you opened up the resulting `modl` file (it's just a zip file) to see if your dependencies are included and declared in the module XML file?

---

<div class="post-metadata">

**Author:** ![BenS](https://avatars.discourse-cdn.com/v4/letter/b/9fc348/32.png) [@BenS](https://forum.inductiveautomation.com/u/BenS)\
**Post date:** [December 11, 2023, 2:01pm UTC](https://forum.inductiveautomation.com/t/include-third-party-dependencies-in-ignition-module/82838/3 "2023-12-11T14:01:44Z")

</div>

Hi Kevin,

Thanks for the quick response and I apologize my response was delayed. I have opened the resulting modl file and verified that the dependencies were not included. They seem to be available at compile time because I did a build with and without linking the dependencies in the gradle build file and the build was only successful when the dependencies were linked.

Here is the gradle build file I am using. It is an edited version of the gradle build file included with the Ignition sample SDK module. I tried using the shadowJar plugin to bundle the dependencies - is that the right approach?

```plaintext

plugins {
    id("io.ia.sdk.modl") version("0.1.1")
    java
    id("com.github.johnrengelman.shadow") version("7.1.2")
}

val sdk_version by extra("8.1.20")

allprojects {
    version = "0.0.1-SNAPSHOT"
}

ignitionModule {
    /*
     * Human readable name of the module, as will be displayed on the gateway status page
     */
    name.set("Ignition DDS Module")

    /*
     * Name of the '.modl' file to be created, without file extension.
     */
    fileName.set("Ignition-DDS-Module.modl")
    /*
     * Unique identifier for the module. Reverse domain convention is recommended (e.g.: com.mycompany.charting-module)
     */
    id.set("com.inductiveautomation.ignition.examples.scripting.IgnitionDDSModule")

    /*
     * Version of the module. Here being set to the same version that gradle uses, up above in this file.
     */
    moduleVersion.set("${project.version}")

    moduleDescription.set("This module allows Ignition to publish and subscribe to DDS topics.")

    /*
     * Minimum version of Ignition required for the module to function correctly. This typically won't change over
     * the course of a major Ignition (7.9, 8.0, etc) version, except for when the Ignition Platform adds/changes APIs
     * used by the module.
     */
    requiredIgnitionVersion.set("8.1.11")
    /*
     * This is a map of String: String, where the 'key' represents the fully qualified path to the project
     * (using gradle path syntax), and the value is the shorthand Scope string.
     * Example entry: listOf( ":gateway" to "G", ":common" to "GC", ":vision-client" to "C" )
     */
    projectScopes.putAll(mapOf(
        ":client" to "CD",
        ":common" to "GCD",
        ":designer" to "D",
        ":gateway" to "G"
    ))

    /*
     * Add your module dependencies here, following the examples, with scope being one or more of G, C or D,
     * for (G)ateway, (D)esigner, Vision (C)lient.
     * Example:
     * moduleDependencies = mapOf(
     * "CD" to "com.inductiveautomation.vision",
     * "G" to "com.inductiveautomation.opcua"
     * )
     */
    moduleDependencies.set(mapOf<String, String>())

    dependencies {
        implementation(fileTree(mapOf("dir" to System.getenv("NDDSHOME") + "/lib/java", "include" to listOf("*.jar"))))
        // Other dependencies
    }

    /*
     * Map of fully qualified hook class to the shorthand scope. Only one scope may apply to a class, and each scope
     * must have no more than single class registered. You may omit scope registrations if they do not apply.
     *
     * Example entry: "com.myorganization.vectorizer.VectorizerDesignerHook" to "D"
     */
    hooks.putAll(mapOf(
        "com.inductiveautomation.ignition.examples.scripting.gateway.GatewayHook" to "G",
        "com.inductiveautomation.ignition.examples.scripting.client.ClientHook" to "C",
        "com.inductiveautomation.ignition.examples.scripting.designer.DesignerHook" to "D"
    ))

    /*
     * Optional 'documentation' settings. Supply the files that would be desired to end up in the 'doc' dir of the
     * assembled module, and specify the path to the index.html file inside that folder. In this commented-out
     * example, the html files being collected are located in the module root project in `src/docs/`
     */
    // the files to collect into the documentation dir, with example implementation
    // documentationFiles.from(project.file("src/docs/"))

    /* The path from the root documentation dir to the index file, or filename if in the root doc dir. */
    // documentationIndex.set("index.html")

    /*
     * Optional unsigned modl settings. If true, modl signing will be skipped. This is not for production and should
     * be used merely for development testing
     */
    skipModlSigning.set(true)
}

tasks {
    shadowJar {
        // Set the classifier to an empty string to replace the default JAR
        archiveClassifier.set("")

        // Include the compile classpath in the JAR
        configurations = listOf(project.configurations.compileClasspath.get())

        // Set the main class in the manifest (if your application has a main class)
        manifest {
            attributes("Main-Class" to "com.your.package.MainClass")
        }
    }
}

repositories {
    mavenCentral()
    maven(url = "https://nexus.inductiveautomation.com/repository/public")

    // Adding a flat directory repository
    flatDir {
        dirs(System.getenv("NDDSHOME") + "/lib/java")
    }
}

```

Thanks again for your help.

---

<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:** [December 11, 2023, 2:03pm UTC](https://forum.inductiveautomation.com/t/include-third-party-dependencies-in-ignition-module/82838/4 "2023-12-11T14:03:50Z")

</div>

> [@BenS](#):
>
> I tried using the shadowJar plugin to bundle the dependencies - is that the right approach?

I don't think it's one we recommend, so you're on your own with that.

In this case, though, you would need to dig further into the main JAR file(s) to see if your dependencies were correctly bundled by the shadow plugin and exist there.

---

<div class="post-metadata">

**Author:** ![BenS](https://avatars.discourse-cdn.com/v4/letter/b/9fc348/32.png) [@BenS](https://forum.inductiveautomation.com/u/BenS)\
**Post date:** [December 11, 2023, 2:05pm UTC](https://forum.inductiveautomation.com/t/include-third-party-dependencies-in-ignition-module/82838/5 "2023-12-11T14:05:28Z")

</div>

What approach (or other plugin) would you recommend for bundling the dependencies into the the modl file?

---

<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:** [December 11, 2023, 2:06pm UTC](https://forum.inductiveautomation.com/t/include-third-party-dependencies-in-ignition-module/82838/6 "2023-12-11T14:06:01Z")

</div>

You don't need an additional plugin to bundle them. The Ignition plugin is making sure they end up in the `modl` file.

---

<div class="post-metadata">

**Author:** ![BenS](https://avatars.discourse-cdn.com/v4/letter/b/9fc348/32.png) [@BenS](https://forum.inductiveautomation.com/u/BenS)\
**Post date:** [December 11, 2023, 2:08pm UTC](https://forum.inductiveautomation.com/t/include-third-party-dependencies-in-ignition-module/82838/7 "2023-12-11T14:08:28Z")

</div>

Ok, I see. I was trying the shadowJar plugin because I was having issues getting them included with the Ignition plugin. I will remove that from the gradle file.

Am I missing anything that I should include to make the Ignition plugin include the dependencies?

---

<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:** [December 11, 2023, 2:09pm UTC](https://forum.inductiveautomation.com/t/include-third-party-dependencies-in-ignition-module/82838/8 "2023-12-11T14:09:02Z")

</div>

You should be defining your dependencies in the sub-modules you create for each scope, not this parent build file.

---

<div class="post-metadata">

**Author:** ![BenS](https://avatars.discourse-cdn.com/v4/letter/b/9fc348/32.png) [@BenS](https://forum.inductiveautomation.com/u/BenS)\
**Post date:** [December 11, 2023, 2:12pm UTC](https://forum.inductiveautomation.com/t/include-third-party-dependencies-in-ignition-module/82838/9 "2023-12-11T14:12:30Z")

</div>

Ok, I had defined the dependencies in each of the submodules as well.

I added this code to the dependencies section in the gradle build file for each submodule:

```plaintext
implementation(fileTree(mapOf("dir" to System.getenv("NDDSHOME") + "/lib/java", "include" to listOf("*.jar"))))

```

I added this code to the repositories section in the gradle build file for each submodule:

```plaintext
flatDir {
    dirs(System.getenv("NDDSHOME") + "/lib/java")
}

```

Anything else I should have added?

---

<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:** [December 11, 2023, 2:14pm UTC](https://forum.inductiveautomation.com/t/include-third-party-dependencies-in-ignition-module/82838/10 "2023-12-11T14:14:34Z")

</div>

Nothing I can think of 🤷‍♂️

I'm not very familiar with our gradle plugin at all, my only advice is to mimic the example the best you can: [https://github.com/inductiveautomation/ignition-sdk-examples/tree/master/perspective-component](https://github.com/inductiveautomation/ignition-sdk-examples/tree/master/perspective-component)

The rest of what you're dealing with is just Ignition-independent gradle stuff.

@PerryAJ any ideas?

---

<div class="post-metadata">

**Author:** ![BenS](https://avatars.discourse-cdn.com/v4/letter/b/9fc348/32.png) [@BenS](https://forum.inductiveautomation.com/u/BenS)\
**Post date:** [December 11, 2023, 2:21pm UTC](https://forum.inductiveautomation.com/t/include-third-party-dependencies-in-ignition-module/82838/11 "2023-12-11T14:21:46Z")

</div>

Thanks Kevin, I will take a look at that.

Is Maven or Gradle more preferred to use with Ignition SDK module development? Gradle was used at [https://github.com/inductiveautomation/ignition-sdk-training](https://github.com/inductiveautomation/ignition-sdk-training) but it looks like a lot of the examples at [https://github.com/inductiveautomation/ignition-sdk-examples](https://github.com/inductiveautomation/ignition-sdk-examples) use Maven.

---

<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:** [December 11, 2023, 2:28pm UTC](https://forum.inductiveautomation.com/t/include-third-party-dependencies-in-ignition-module/82838/12 "2023-12-11T14:28:41Z")

</div>

The Maven plugin was the original but isn't maintained any more.

The Gradle plugin is the current and supported one.

Most of the examples pre-date the Gradle plugin's existence.

---

<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:** [December 11, 2023, 2:43pm UTC](https://forum.inductiveautomation.com/t/include-third-party-dependencies-in-ignition-module/82838/13 "2023-12-11T14:43:09Z")

</div>

> [@BenS](#):
>
> added this code to the dependencies section in the gradle build file for each submodule:

You need to be declaring the dependencies you want your final module to include with an `modlApi` or `modlImplementation` declaration, rather than `implementation`. `implementation` is what allows it to compile, but `modlApi` is the signal to the module plugin that it's actually going to be part of the output and therefore should be included there. See example here: [https://github.com/inductiveautomation/ignition-sdk-examples/blob/master/perspective-component%2Fgateway%2Fbuild.gradle.kts#L17](https://github.com/inductiveautomation/ignition-sdk-examples/blob/master/perspective-component%2Fgateway%2Fbuild.gradle.kts#L17)

I don't know if that will work with your file based approach, though; the recommended pattern is to either use public Maven repositories or host your own compatible instance locally, rather than relying on raw JARs on your local filesystem, so I don't think our plugin has ever been tested with your approach. You can certainly give it a try, though.

---

<div class="post-metadata">

**Author:** ![BenS](https://avatars.discourse-cdn.com/v4/letter/b/9fc348/32.png) [@BenS](https://forum.inductiveautomation.com/u/BenS)\
**Post date:** [December 11, 2023, 2:49pm UTC](https://forum.inductiveautomation.com/t/include-third-party-dependencies-in-ignition-module/82838/14 "2023-12-11T14:49:21Z")

</div>

Thank you, I will give that a try. Is there a difference between `modlApi` and `modlImplementation`, or are they equivalent?

---

<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:** [December 11, 2023, 2:51pm UTC](https://forum.inductiveautomation.com/t/include-third-party-dependencies-in-ignition-module/82838/15 "2023-12-11T14:51:37Z")

</div>

I believe there's no actual difference in the way our current module system works, but it's theoretically more clear to a third party coming and looking at your code.  
That is, implementation should be used for "private" dependencies that only matter to one particular execution scope, and api should be used for dependencies that will be re-exported for further use downstream.

---

<div class="post-metadata">

**Author:** ![BenS](https://avatars.discourse-cdn.com/v4/letter/b/9fc348/32.png) [@BenS](https://forum.inductiveautomation.com/u/BenS)\
**Post date:** [December 11, 2023, 3:21pm UTC](https://forum.inductiveautomation.com/t/include-third-party-dependencies-in-ignition-module/82838/16 "2023-12-11T15:21:57Z")

</div>

I used `modlImplementation` and successfully included the jar file in the `modl` file. However, I am still running into errors when I test the module by running a command in Script Console in designer that seem to indicate that the third-party jar is not available. How would I check to ensure that the third-party jar is available in the classpath at runtime?

My Script Console output is below:

```auto
Jython 2.7.2 (uncontrolled:000000000000, Jan 25 2022, 14:39:15)
[OpenJDK 64-Bit Server VM (Azul Systems, Inc.)] on java11.0.18

>>> 
Java Traceback:
Traceback (most recent call last):
  File "<input>", line 1, in <module>
	at com.sun.proxy.$Proxy58.startPublishing(Unknown Source)
	at com.inductiveautomation.ignition.examples.scripting.client.ClientScriptModule.startPublishingOnServer(ClientScriptModule.java:18)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
java.lang.reflect.UndeclaredThrowableException: java.lang.reflect.UndeclaredThrowableException

	at org.python.core.Py.JavaError(Py.java:547)
	at org.python.core.Py.JavaError(Py.java:538)
	at org.python.core.PyReflectedFunction. __call__ (PyReflectedFunction.java:192)
	at com.inductiveautomation.ignition.common.script.ScriptManager$ReflectedInstanceFunction. __call__ (ScriptManager.java:552)
	at org.python.core.PyObject. __call__ (PyObject.java:461)
	at org.python.core.PyObject. __call__ (PyObject.java:465)
	at org.python.pycode._pyx6.f$0(<input>:1)
	at org.python.pycode._pyx6.call_function(<input>)
	at org.python.core.PyTableCode.call(PyTableCode.java:173)
	at org.python.core.PyCode.call(PyCode.java:18)
	at org.python.core.Py.runCode(Py.java:1687)
	at org.python.core.Py.exec(Py.java:1731)
	at org.python.util.PythonInterpreter.exec(PythonInterpreter.java:277)
	at org.python.util.InteractiveInterpreter.runcode(InteractiveInterpreter.java:130)
	at com.inductiveautomation.ignition.designer.gui.tools.jythonconsole.JythonConsole$ConsoleWorker.doInBackground(JythonConsole.java:626)
	at com.inductiveautomation.ignition.designer.gui.tools.jythonconsole.JythonConsole$ConsoleWorker.doInBackground(JythonConsole.java:614)
	at java.desktop/javax.swing.SwingWorker$1.call(Unknown Source)
	at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
	at java.desktop/javax.swing.SwingWorker.run(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.lang.reflect.UndeclaredThrowableException
	at com.sun.proxy.$Proxy58.startPublishing(Unknown Source)
	at com.inductiveautomation.ignition.examples.scripting.client.ClientScriptModule.startPublishingOnServer(ClientScriptModule.java:18)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	at org.python.core.PyReflectedFunction. __call__ (PyReflectedFunction.java:190)
	... 19 more
Caused by: com.inductiveautomation.ignition.client.gateway_interface.GatewayException: Could not initialize class com.rti.dds.domain.DomainParticipantFactory
	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.newGatewayException(GatewayInterface.java:351)
	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.sendMessage(GatewayInterface.java:325)
	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.sendMessage(GatewayInterface.java:278)
	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.moduleInvokeSafe(GatewayInterface.java:917)
	at com.inductiveautomation.ignition.client.gateway_interface.ModuleRPCFactory$DynamicRPCHandler.invoke(ModuleRPCFactory.java:53)
	... 26 more
Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.rti.dds.domain.DomainParticipantFactory
	at com.inductiveautomation.ignition.examples.scripting.common.HMItoSICCommand.dispose(HMItoSICCommand.java:43)
	at com.inductiveautomation.ignition.examples.scripting.common.HMItoSICCommand.startPublishing(HMItoSICCommand.java:91)
	at com.inductiveautomation.ignition.examples.scripting.gateway.GatewayScriptModule.startPublishing(GatewayScriptModule.java:16)
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(null)
	at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(null)
	at java.lang.reflect.Method.invoke(null)
	at com.inductiveautomation.ignition.gateway.servlets.gateway.functions.ModuleInvoke.invoke(ModuleInvoke.java:167)
	at com.inductiveautomation.ignition.gateway.servlets.Gateway.doPost(Gateway.java:434)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:523)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:590)
	at com.inductiveautomation.ignition.gateway.bootstrap.MapServlet.service(MapServlet.java:86)
	at org.eclipse.jetty.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1410)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:764)
	at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1665)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:527)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:131)
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:578)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:223)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1570)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1383)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:484)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1543)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1305)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
	at com.inductiveautomation.catapult.handlers.RemoteHostNameLookupHandler.handle(RemoteHostNameLookupHandler.java:121)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
	at org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:301)
	at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:51)
	at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:141)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
	at org.eclipse.jetty.server.Server.handle(Server.java:563)
	at org.eclipse.jetty.server.HttpChannel.lambda$handle$0(HttpChannel.java:505)
	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:762)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:497)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:282)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:314)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)
	at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:416)
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:385)
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:272)
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.lambda$new$0(AdaptiveExecutionStrategy.java:140)
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:411)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:934)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1078)
	at java.lang.Thread.run(null)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
	at com.sun.proxy.$Proxy58.startPublishing(Unknown Source)
	at com.inductiveautomation.ignition.examples.scripting.client.ClientScriptModule.startPublishingOnServer(ClientScriptModule.java:18)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
java.lang.reflect.UndeclaredThrowableException: java.lang.reflect.UndeclaredThrowableException
>>> 

```

---

<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:** [December 11, 2023, 3:24pm UTC](https://forum.inductiveautomation.com/t/include-third-party-dependencies-in-ignition-module/82838/17 "2023-12-11T15:24:35Z")

</div>

> [@BenS](#):
>
> ```auto
> Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.rti.dds.domain.DomainParticipantFactory
> at com.inductiveautomation.ignition.examples.scripting.common.HMItoSICCommand.dispose(HMItoSICCommand.java:43)
> at com.inductiveautomation.ignition.examples.scripting.common.HMItoSICCommand.startPublishing(HMItoSICCommand.java:91)
> at com.inductiveautomation.ignition.examples.scripting.gateway.GatewayScriptModule.startPublishing(GatewayScriptModule.java:16)
> 
> ```

Based on this error I'm assuming you're using the RPC pattern because this looks to be executing in gateway scope.

Start by looking at the module.xml file that was generated and included with your module to make sure all of your expected dependencies are listed and have a "G" scope specifier.

---

<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:** [December 11, 2023, 3:26pm UTC](https://forum.inductiveautomation.com/t/include-third-party-dependencies-in-ignition-module/82838/18 "2023-12-11T15:26:24Z")

</div>

> [@Kevin.Herron](#):
>
> you're using the RPC pattern because this looks to be executing in gateway scope.

Or, if you want execution to actually happen in the local designer scope, package your dependency appropriately. What solution works best is up to you.

---

<div class="post-metadata">

**Author:** ![BenS](https://avatars.discourse-cdn.com/v4/letter/b/9fc348/32.png) [@BenS](https://forum.inductiveautomation.com/u/BenS)\
**Post date:** [December 11, 2023, 3:28pm UTC](https://forum.inductiveautomation.com/t/include-third-party-dependencies-in-ignition-module/82838/19 "2023-12-11T15:28:15Z")

</div>

Per the module.xml file, it looks like the jar (nddsjava.jar) is included in the designer, gateway, and client scopes. See below:

```auto
<?xml version="1.0" encoding="UTF-8"?>
<modules>
	<module>
		<name>Ignition DDS Module</name>
		<id>com.inductiveautomation.ignition.examples.scripting.IgnitionDDSModule</id>
		<version>0.0.1-SNAPSHOT</version>
		<description>This module allows Ignition to publish and subscribe to DDS topics.</description>
		<requiredIgnitionVersion>8.1.11</requiredIgnitionVersion>
		<freeModule>false</freeModule>
		<hook scope="G">com.inductiveautomation.ignition.examples.scripting.gateway.GatewayHook</hook>
		<hook scope="C">com.inductiveautomation.ignition.examples.scripting.client.ClientHook</hook>
		<hook scope="D">com.inductiveautomation.ignition.examples.scripting.designer.DesignerHook</hook>
		<requiredFrameworkVersion>8</requiredFrameworkVersion>
		<jar scope="CD">client-0.0.1-SNAPSHOT.jar</jar>
		<jar scope="CDG">nddsjava.jar</jar>
		<jar scope="CDG">common-0.0.1-SNAPSHOT.jar</jar>
		<jar scope="D">designer-0.0.1-SNAPSHOT.jar</jar>
		<jar scope="G">gateway-0.0.1-SNAPSHOT.jar</jar>
	</module>
</modules>

```

---

<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:** [December 11, 2023, 3:29pm UTC](https://forum.inductiveautomation.com/t/include-third-party-dependencies-in-ignition-module/82838/20 "2023-12-11T15:29:16Z")

</div>

Ok, make sure the class file referenced in the error actually exists in that JAR, and that you aren't missing any other dependencies.

edit: though I'd bet what is actually happening is that it does exist, and an Exception is being thrown during its static initializer.

[Next page](https://forum.inductiveautomation.com/t/include-third-party-dependencies-in-ignition-module/82838.md?page=2)
