Re: Problems creating custom appender using JPMS service in 3.0.0-beta3

Matt Sicker <[email protected]> Mon, 2 Dec 2024 12:36:41 -0600
Newsgroups gmane.comp.jakarta.log4j.user
Message-ID <[email protected]>
For one, you=E2=80=99ll need to annotate your constructor arguments with =
the appropriate @Plugin annotations (@PluginElement and @PluginAttribute =
mainly) to know how to bind config data to your plugin. That is required =
regardless of whether you=E2=80=99re manually generating the metadata =
file for plugin descriptors (which is mainly used as a sort of component =
index to avoid classpath scanning at runtime).

While I do recommend the annotation processor, at least in 2.x, that was =
written to replace a main() method in a class somewhere you could invoke =
that generated the same metadata, and said metadata was used to avoid =
the need for specifying package names to scan at runtime in your config =
file to find custom plugins (something that bothered me personally in =
unit tests since we had test plugins to import everywhere). Due to =
strong encapsulation of Java modules, we had to abandon generic =
classpath scanning in 3.x, hence the need for the metadata file. I =
suppose this is something that=E2=80=99s not set in stone yet for 3.0.0, =
so we can look more into this.

> On Nov 28, 2024, at 08:47, PavelTurk <[email protected]> wrote:
>=20
> Hello everyone.
>=20
> I am trying to create my own appender using JPMS service in =
3.0.0-beta3. This is my code:
>=20
> import org.apache.logging.log4j.core.Appender;
> import org.apache.logging.log4j.core.Filter;
> import org.apache.logging.log4j.core.Layout;
> import org.apache.logging.log4j.core.LogEvent;
> import org.apache.logging.log4j.core.appender.AbstractAppender;
> import org.apache.logging.log4j.core.config.Property;
> import org.apache.logging.log4j.plugins.Configurable;
> import org.apache.logging.log4j.plugins.Plugin;
>=20
> @Plugin("Foo")
> @Configurable(elementType =3D Appender.ELEMENT_TYPE, printObject =3D =
true)
> public class FooAppender extends AbstractAppender {
>=20
>     public FooAppender(String name, Filter filter, Layout layout, =
boolean ignoreExceptions, Property[] properties) {
>         super(name, filter, layout, ignoreExceptions, properties);
>     }
>=20
>     @Override
>     public void append(LogEvent event) {
>         System.out.println("Event:" + event.getMessage());
>     }
> }
>=20
> import org.apache.logging.log4j.plugins.model.PluginEntry;
> import org.apache.logging.log4j.plugins.model.PluginService;
>=20
> public class PluginProvider extends PluginService {
>=20
>     private static PluginEntry[] entries =3D new PluginEntry[] {
>         PluginEntry.builder()
>             .setKey("foo")
>             .setClassName("com.foo.FooAppender")
>             .setName("Foo")
>             .setNamespace("Core")//I tried to use my namespace - it =
didn't help
>             .setElementType("appender")
>             .setPrintable(true)
>             .get(),
>     };
>=20
>     @Override
>     public PluginEntry[] getEntries() {
>         System.out.println("ENTRIES OK"); // I didn't get this point
>         return entries;
>     }
> }
>=20
> module-info:
>=20
> opens com.foo;
> provides org.apache.logging.log4j.plugins.model.PluginService with =
com.foo.PluginProvider;
>=20
> Config:
>=20
> <?xml version=3D"1.0" encoding=3D"UTF-8"?>
> <Configuration status=3D"error" shutdownHook=3D"disable">
>     <Appenders>
>          <Foo name=3D"Foo"/>
>      </Appenders>
>     <Loggers>
>         <Root level=3D"debug">
>             <AppenderRef ref=3D"Foo"/>
>         </Root>
>    </Loggers>
> </Configuration>
>=20
> Result:
> Exception in thread "main" =
org.apache.logging.log4j.plugins.di.spi.ReflectionException
>     at =
[email protected]/org.apache.logging.log4j.plug=
ins.di.spi.ReflectionAgent.invokeMethod(ReflectionAgent.java:84)
>     at =
[email protected]/org.apache.logging.log4j.plug=
ins.di.DefaultInstanceFactory.lambda$registerBundleMethod$13(DefaultInstan=
ceFactory.java:306)
>     at =
[email protected]/org.apache.logging.log4j.util.LazyUtil$Saf=
eLazy.value(LazyUtil.java:113)
>     at =
[email protected]/org.apache.logging.log4j.util.Lazy.get(Laz=
y.java:39)
>     at =
[email protected]/org.apache.logging.log4j.plug=
ins.di.InstanceFactory.getInstance(InstanceFactory.java:126)
>     at =
[email protected]/org.apache.logging.log4j.plug=
ins.di.DefaultInstanceFactory.lambda$getArgumentFactory$9(DefaultInstanceF=
actory.java:223)
>     at =
java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.=
java:212)
>     at =
java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayL=
ist.java:1709)
>     at =
java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java=
:556)
>     at =
java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeli=
ne.java:546)
>     at =
java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java=
:622)
>     at =
java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPi=
peline.java:291)
>     at =
java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.jav=
a:631)
>     at =
java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.jav=
a:637)
>     at =
[email protected]/org.apache.logging.log4j.plug=
ins.di.DefaultInstanceFactory.lambda$registerBundleMethod$13(DefaultInstan=
ceFactory.java:305)
>     at =
[email protected]/org.apache.logging.log4j.util.LazyUtil$Saf=
eLazy.value(LazyUtil.java:113)
>     at =
[email protected]/org.apache.logging.log4j.util.Lazy.get(Laz=
y.java:39)
>     at =
[email protected]/org.apache.logging.log4j.plug=
ins.di.InstanceFactory.getInstance(InstanceFactory.java:115)
>     at =
[email protected]/org.apache.logging.log4j.core.Lo=
ggerContext.<init>(LoggerContext.java:149)
>     at =
[email protected]/org.apache.logging.log4j.core.Lo=
ggerContext$Builder.build(LoggerContext.java:996)
>     at =
[email protected]/org.apache.logging.log4j.core.se=
lector.AbstractContextSelector.createContext(AbstractContextSelector.java:=
42)
>     at =
[email protected]/org.apache.logging.log4j.core.se=
lector.ClassLoaderContextSelector.locateContext(ClassLoaderContextSelector=
.java:231)
>     at =
[email protected]/org.apache.logging.log4j.core.se=
lector.ClassLoaderContextSelector.getContext(ClassLoaderContextSelector.ja=
va:149)
>     at =
[email protected]/org.apache.logging.log4j.core.se=
lector.ClassLoaderContextSelector.getContext(ClassLoaderContextSelector.ja=
va:132)
>     at =
[email protected]/org.apache.logging.log4j.core.se=
lector.ClassLoaderContextSelector.getContext(ClassLoaderContextSelector.ja=
va:126)
>     at =
[email protected]/org.apache.logging.log4j.core.im=
pl.Log4jContextFactory.getContext(Log4jContextFactory.java:151)
>     at =
[email protected]/org.apache.logging.log4j.core.im=
pl.Log4jContextFactory.getContext(Log4jContextFactory.java:49)
>     at =
[email protected]/org.apache.logging.log4j.LogManager.getCon=
text(LogManager.java:138)
>     at =
[email protected]/org.apache.logging.log4j.spi.AbstractLogge=
rAdapter.getContext(AbstractLoggerAdapter.java:136)
>     at =
[email protected]/org.apache.logging.slf4j.Log4j=
LoggerFactory.getContext(Log4jLoggerFactory.java:58)
>     at =
[email protected]/org.apache.logging.log4j.spi.AbstractLogge=
rAdapter.getLogger(AbstractLoggerAdapter.java:46)
>     at =
[email protected]/org.apache.logging.slf4j.Log4j=
LoggerFactory.getLogger(Log4jLoggerFactory.java:32)
>     at =
[email protected]/org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:426)
>     at =
[email protected]/org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:451)
>=20
> So, java dies in main class where I initializer my logger.
> Could anyone say: 1) how to fix it 2) How to use custom Namespace for =
my appender in configuration?
> For example, if I do PluginEntry.builder().setNamespace("FooNS")?
>=20
> Best regards, Pavel
>=20
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>=20