# Usage of META-INF.services in module?

**URL:** <https://forum.inductiveautomation.com/t/usage-of-meta-inf-services-in-module/83846>\
**Category:** Module Development\
**Tags:** ignition81\
**Created:** [January 5, 2024, 4:01pm UTC](https://forum.inductiveautomation.com/t/usage-of-meta-inf-services-in-module/83846 "2024-01-05T16:01:51Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![mazeyrat](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mazeyrat/32/10955_2.png) [@mazeyrat](https://forum.inductiveautomation.com/u/mazeyrat)\
**Post date:** [January 5, 2024, 4:01pm UTC](https://forum.inductiveautomation.com/t/usage-of-meta-inf-services-in-module/83846/1 "2024-01-05T16:01:51Z")

</div>

Hello,

I have a module which need to use **META -INF.services**.

> **[ServiceLoader (Java SE 17 & JDK 17)](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/ServiceLoader.html)**
>
> declaration: module: java.base, package: java.util, class: ServiceLoader

A third party dependency need to load a class provided in the META -INF.services.

**Is it possible ?**

When the third party dependency try to load it, I have an exception.

I have ever tried something like this before the third party look for it.

```auto
 ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
  try{

    Thread.currentThread().setContextClassLoader(UtilsGst.class.getClassLoader());
    xxxxxxxxx

 } finally {
            Thread.currentThread().setContextClassLoader(classLoader);
 }

```

---

<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:** [January 5, 2024, 5:02pm UTC](https://forum.inductiveautomation.com/t/usage-of-meta-inf-services-in-module/83846/2 "2024-01-05T17:02:28Z")

</div>

What's the Exception?

None of our modules use the ServiceLoader mechanism so I'm not able to tell you if there's something making this fundamentally impossible or not.

---

<div class="post-metadata">

**Author:** ![mazeyrat](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mazeyrat/32/10955_2.png) [@mazeyrat](https://forum.inductiveautomation.com/u/mazeyrat)\
**Post date:** [January 5, 2024, 5:21pm UTC](https://forum.inductiveautomation.com/t/usage-of-meta-inf-services-in-module/83846/3 "2024-01-05T17:21:32Z")

</div>

When the third party look for the class named in

com/bouyguesenergiesservices/ignition/common/videoviewer/  
META-INF/org.freedesktop.gstreamer.glib.NativeObject$TypeProvider:

```auto
com.bouyguesenergiesservices.ignition.common.videoviewer.Types

```

it can't find it.  
Stack trace:

```auto
java.lang.RuntimeException: java.lang.InstantiationException

at org.freedesktop.gstreamer.glib.NativeObject.objectFor(NativeObject.java:195)

at org.freedesktop.gstreamer.glib.Natives.objectFor(Natives.java:166)

at org.freedesktop.gstreamer.glib.Natives.callerOwnsReturn(Natives.java:140)

at org.freedesktop.gstreamer.lowlevel.GTypeMapper$2.fromNative(GTypeMapper.java:113)

at com.sun.jna.Function.invoke(Function.java:370)

at com.sun.jna.Library$Handler.invoke(Library.java:270)

at jdk.proxy3/jdk.proxy3.$Proxy123.g_value_dup_object(Unknown Source)

at org.freedesktop.gstreamer.glib.GObject.get(GObject.java:194)

...

at java.base/java.lang.Thread.run(Unknown Source)

Caused by: java.lang.InstantiationException: null

at java.base/jdk.internal.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(Unknown Source)

at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Unknown Source)

at java.base/java.lang.reflect.Constructor.newInstance(Unknown Source)

at org.freedesktop.gstreamer.glib.NativeObject.objectFor(NativeObject.java:187)

... 44 common frames omitted

```

---

<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:** [January 5, 2024, 5:26pm UTC](https://forum.inductiveautomation.com/t/usage-of-meta-inf-services-in-module/83846/4 "2024-01-05T17:26:37Z")

</div>

I don't think your `META-INF` folder is in the correct location. It should be at the root of your JAR file.

---

<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:** [January 5, 2024, 5:28pm UTC](https://forum.inductiveautomation.com/t/usage-of-meta-inf-services-in-module/83846/5 "2024-01-05T17:28:55Z")

</div>

Old repo, but look at the structure here:

> <https://github.com/paul-griffith/kindling-extension/tree/main/src/main/resources/META-INF/services>
>
> //github.com/paul-griffith/kindling-extension/tree/main/src/main/resources/META-INF/services

All of your modules provided jars should be on the same classloader, so I think this should fundamentally work.

---

<div class="post-metadata">

**Author:** ![mazeyrat](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mazeyrat/32/10955_2.png) [@mazeyrat](https://forum.inductiveautomation.com/u/mazeyrat)\
**Post date:** [January 5, 2024, 5:39pm UTC](https://forum.inductiveautomation.com/t/usage-of-meta-inf-services-in-module/83846/6 "2024-01-05T17:39:09Z")

</div>

seem to be ok ? or I need to put the META-INF.services at another location ???

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/9/d/9df9efb75c27fe09b4bdd542a40436f03d22f185.png)

---

<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:** [January 5, 2024, 5:41pm UTC](https://forum.inductiveautomation.com/t/usage-of-meta-inf-services-in-module/83846/7 "2024-01-05T17:41:34Z")

</div>

It's not "META-INF.services", it's "META-INF/services". Two directories.

(not sure if that's what you have or it's just the IDE showing it that way)

---

<div class="post-metadata">

**Author:** ![mazeyrat](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mazeyrat/32/10955_2.png) [@mazeyrat](https://forum.inductiveautomation.com/u/mazeyrat)\
**Post date:** [January 5, 2024, 5:43pm UTC](https://forum.inductiveautomation.com/t/usage-of-meta-inf-services-in-module/83846/8 "2024-01-05T17:43:18Z")

</div>

Yes that IJ showing folder in that way

---

<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:** [January 5, 2024, 5:58pm UTC](https://forum.inductiveautomation.com/t/usage-of-meta-inf-services-in-module/83846/9 "2024-01-05T17:58:30Z")

</div>

Do you have a no-arg constructor, explicit or implicit, in your service implementation class?

---

<div class="post-metadata">

**Author:** ![mazeyrat](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mazeyrat/32/10955_2.png) [@mazeyrat](https://forum.inductiveautomation.com/u/mazeyrat)\
**Post date:** [January 5, 2024, 6:02pm UTC](https://forum.inductiveautomation.com/t/usage-of-meta-inf-services-in-module/83846/10 "2024-01-05T18:02:28Z")

</div>

the service implementation class:

```auto
package org.freedesktop.gstreamer.examples;

import java.util.stream.Stream;
import org.freedesktop.gstreamer.glib.NativeObject;
import org.freedesktop.gstreamer.glib.Natives;

/**
 * Custom type registration for WebRTC example. This class is registered in
 * META-INF/services to be picked up by the {@link ServiceLoader}.
 */
public class Types implements NativeObject.TypeProvider {

    @Override
    public Stream<NativeObject.TypeRegistration<?>> types() {
        return Stream.of(
                Natives.registration(WebRTCICE.class, WebRTCICE.GTYPE_NAME, WebRTCICE::new)
        );
    }

}

```

---

<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:** [January 5, 2024, 6:07pm UTC](https://forum.inductiveautomation.com/t/usage-of-meta-inf-services-in-module/83846/11 "2024-01-05T18:07:34Z")

</div>

> [@mazeyrat](#):
>
> org.freedesktop.gstreamer.glib.NativeObject$TypeProvider

Should the file actually be called `org.freedesktop.gstreamer.glib.NativeObject.TypeProvider`?

since TypeProvider is a static inner class?

---

<div class="post-metadata">

**Author:** ![mazeyrat](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mazeyrat/32/10955_2.png) [@mazeyrat](https://forum.inductiveautomation.com/u/mazeyrat)\
**Post date:** [January 5, 2024, 7:12pm UTC](https://forum.inductiveautomation.com/t/usage-of-meta-inf-services-in-module/83846/12 "2024-01-05T19:12:44Z")

</div>

I think I've have finally something which works, but I need to understand after multiples code changes.

- Thread.currentThread().setContextClassLoader before the initial third-party lib init in the -common
- Thread.currentThread().setContextClassLoader before the call of the function in the -gateway

both files added:

- org.freedesktop.gstreamer.glib.NativeObject.TypeProvider
- org.freedesktop.gstreamer.glib.NativeObject$TypeProvider

with reference to:

- com.bouyguesenergiesservices.ignition.common.videoviewer.Types

I will see what it's necessary.
