This is an automated email from the ASF dual-hosted git repository.

vy pushed a commit to branch doc/2.x/extending
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git

commit d495947f48895810b6be8788f85f859333ce2226
Author: Volkan Yazıcı <[email protected]>
AuthorDate: Wed Jun 12 11:03:58 2024 +0200

    Rewrite `plugins.adoc`
---
 .../modules/ROOT/pages/manual/extending.adoc       | 119 ---------
 .../antora/modules/ROOT/pages/manual/plugins.adoc  | 278 +++++++++++++++++----
 src/site/resources/.htaccess                       |   3 +
 3 files changed, 234 insertions(+), 166 deletions(-)

diff --git a/src/site/antora/modules/ROOT/pages/manual/extending.adoc 
b/src/site/antora/modules/ROOT/pages/manual/extending.adoc
index 6b3e67233e..4ce2ac3333 100644
--- a/src/site/antora/modules/ROOT/pages/manual/extending.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/extending.adoc
@@ -208,125 +208,6 @@ a separate `FlowMessageFactory`. Applications may replace 
the
 `log4j2.flowMessageFactory` to the name of the custom `FlowMessageFactory`
 class.
 
-[#Plugin_Builders]
-== Plugin Builders
-
-Some plugins take a lot of optional configuration options. When a plugin
-takes many options, it is more maintainable to use a builder class
-rather than a factory method (see _Item 2: Consider a builder when faced
-with many constructor parameters_ in _Effective Java_ by Joshua Bloch).
-There are some other advantages to using an annotated builder class over
-an annotated factory method:
-
-* Attribute names don't need to be specified if they match the field name or 
the parameter name.
-* Default values can be specified in code rather than through an
-annotation (also allowing a runtime-calculated default value which isn't
-allowed in annotations).
-* Adding new optional parameters doesn't require existing programmatic
-configuration to be refactored.
-* Easier to write unit tests using builders rather than factory methods
-with optional parameters.
-* Default values are specified via code rather than relying on
-reflection and injection, so they work programmatically as well as in a
-configuration file.
-
-Here is an example of a plugin factory from `ListAppender`:
-
-[source,java]
-----
-@PluginFactory
-public static ListAppender createAppender(
-        @PluginAttribute("name") @Required(message = "No name provided for 
ListAppender") final String name,
-        @PluginAttribute("entryPerNewLine") final boolean newLine,
-        @PluginAttribute("raw") final boolean raw,
-        @PluginElement("Layout") final Layout<? extends Serializable> layout,
-        @PluginElement("Filter") final Filter filter) {
-    return new ListAppender(name, filter, layout, newLine, raw);
-}
-----
-
-Here is that same factory using a builder pattern instead:
-
-[source,java]
-----
-@PluginBuilderFactory
-public static Builder newBuilder() {
-    return new Builder();
-}
-
-public static class Builder implements 
org.apache.logging.log4j.core.util.Builder<ListAppender> {
-
-    @PluginBuilderAttribute
-    @Required(message = "No name provided for ListAppender")
-    private String name;
-
-    @PluginBuilderAttribute
-    private boolean entryPerNewLine;
-
-    @PluginBuilderAttribute
-    private boolean raw;
-
-    @PluginElement("Layout")
-    private Layout<? extends Serializable> layout;
-
-    @PluginElement("Filter")
-    private Filter filter;
-
-    public Builder setName(final String name) {
-        this.name = name;
-        return this;
-    }
-
-    public Builder setEntryPerNewLine(final boolean entryPerNewLine) {
-        this.entryPerNewLine = entryPerNewLine;
-        return this;
-    }
-
-    public Builder setRaw(final boolean raw) {
-        this.raw = raw;
-        return this;
-    }
-
-    public Builder setLayout(final Layout<? extends Serializable> layout) {
-        this.layout = layout;
-        return this;
-    }
-
-    public Builder setFilter(final Filter filter) {
-        this.filter = filter;
-        return this;
-    }
-
-    @Override
-    public ListAppender build() {
-        return new ListAppender(name, filter, layout, entryPerNewLine, raw);
-    }
-}
-----
-
-The only difference in annotations is using `@PluginBuilderAttribute` instead 
of `@PluginAttribute`
-so that default values and reflection can be used instead of specifying them 
in the annotation.
-Either annotation can be used in a builder, but the former is better suited 
for field injection
-while the latter is better suited for parameter injection. Otherwise, the same 
annotations
-(`@PluginConfiguration`, `@PluginElement`, `@PluginNode`, and `@PluginValue`) 
are all supported on fields.
-Note that a factory method is still required to supply a builder, and this 
factory method
-should be annotated with `@PluginBuilderFactory`.
-
-When plugins are being constructed after a configuration has been
-parsed, a plugin builder will be used if available, otherwise a plugin
-factory method will be used as a fallback. If a plugin contains neither
-factory, then it cannot be used from a configuration file (it can still
-be used programmatically of course).
-
-Here is an example of using a plugin factory versus a plugin builder
-programmatically:
-
-[source,java]
-----
-ListAppender list1 = ListAppender.createAppender("List1", true, false, null, 
null);
-ListAppender list2 = 
ListAppender.newBuilder().setName("List1").setEntryPerNewLine(true).build();
-----
-
 [#Custom_Plugins]
 == Custom Plugins
 
diff --git a/src/site/antora/modules/ROOT/pages/manual/plugins.adoc 
b/src/site/antora/modules/ROOT/pages/manual/plugins.adoc
index c793d404c4..cbca9ff4ec 100644
--- a/src/site/antora/modules/ROOT/pages/manual/plugins.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/plugins.adoc
@@ -14,39 +14,227 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 ////
+
 = Plugins
 
-Log4j 1.x allowed for extension by requiring class attributes on most of the 
configuration declarations. In the case of some elements, notably the 
PatternLayout, the only way to add new pattern converters was to extend the 
PatternLayout class and add them via code. One goal of Log4j 2 is to make 
extending it extremely easy through the use of plugins.
+Log4j plugin system is the de facto extension mechanism embraced by various 
Log4j Core components.
+Plugins make it possible for extensible components to _receive_ feature 
implementations without any explicit links in between.
+It is analogous to a 
https://en.wikipedia.org/wiki/Dependency_injection[dependency injection] 
framework, but curated for Log4j-specific needs.
+
+[NOTE]
+====
+Log4j plugin system is implemented by Log4j Core, the logging implementation.
+It is deliberately not a part of the Log4j API to keep the logging API 
footprint small.
+====
+
+[TIP]
+====
+Did you know about *xref:plugin-reference.adoc[], the documentation extracted 
from the source code* of all predefined Log4j plugins?
+Like Javadoc, but specialized for plugins!
+====
+
+In this section we will give an overview of the Log4j plugin system by 
answering certain questions:
+
+. <<#declare-plugin,How can you declare a plugin?>>
+. <<#core,How can you declare a plugin that needs to be represented in a Log4j 
configuration file?>>
+. <<#plugin-registry,How can you register your plugin to Log4j?>>
+. <<#plugin-discovery,How does Log4j discover plugins?>>
+. <<#plugin-load,How can you load other plugins in a plugin?>>
+
+[#declare-plugin]
+== Declaring plugins
+
+A class can be declared as a plugin by adding a 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/Plugin.html[`@Plugin`]
 annotation, which is essentially composed of following attributes:
+
+`name`::
+Denotes the name of the plugin and is recommended to be distinct among plugins 
sharing the same `category`.
+`name` matching is case-insensitive.
+
+`category`::
+A name used for grouping a set of plugins.
+`name` matching is case-sensitive.
+
+`elementType`::
+Name of the corresponding category of the xref:manual/configuration.adoc[Log4j 
configuration] file element this plugin belongs under.
+You can omit this attribute if your plugin is not meant to be represented in a 
configuration file.
+
+For example, xref:manual/lookups.adoc#extending[lookups] only use the 
`category` attribute and set it to 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrLookup.html#CATEGORY[`StrLookup.CATEGORY`]
 (`Lookup`).
+On the other hand, xref:manual/appenders.adoc#extending[appenders] use both 
the `category` and `elementType` attributes and set them to 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Node.html#CATEGORY[`Node.CATEGORY`]
 (`Core`) and 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/Appender.html#ELEMENT_TYPE[`Appender.ELEMENT_TYPE`]
 (`appender`), respectively.
+The reason appenders use an `elementType` and lookups don't is that appenders 
need to be referred to in an element in a Log4j configuration file (e.g., 
`log4j2.xml`) whereas lookups don't.
+See <<core>> for details.
+
+For clarity's sake, see following examples:
+
+* 
{project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/DateLookup.java[`LowerLookup.java`]
 (uses only `category`)
+* 
{project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/CsvParameterLayout.java[`CsvParameterLayout.java`]
 (uses both `category` and `elementType`)
+
+.Click to read more on *name collision* and *overriding an existing plugin*
+[%collapsible]
+====
+The `name` attribute of plugins of a certain `category` is recommended to be 
distinct and this matching is case-insensitive.
+In case of a name collision, a warning will be emitted, and the plugin 
<<plugin-discovery,discovery order>> will determine the effective plugin.
+For example, to override the `File` plugin which is provided by the built-in 
xref:manual/appenders.adoc#FileAppender[File Appender], you would need to place 
your plugin in a JAR file in the classpath ahead of Log4j Core JAR.
+In an OSGi environment, the order that bundles are scanned for plugins 
generally follows the same order that bundles were installed into the 
framework; see 
https://www.osgi.org/javadoc/r5/core/org/osgi/framework/BundleContext.html#getBundles()[`getBundles()`]
 and 
https://www.osgi.org/javadoc/r5/core/org/osgi/framework/SynchronousBundleListener.html[`SynchronousBundleListener`].
+In short, name collisions are even more unpredictable in an OSGi environment.
+====
+
+[#core]
+== Declaring plugins represented in a configuration file
+
+If your plugin needs to be represented by an element in a configuration file 
(such as an xref:manual/appenders.adoc[appender], 
xref:manual/layouts.adoc[layout], xref:manual/api.adoc#loggers[logger], or 
xref:manual/filters.adoc[filter]), following requirements must be met:
+
+* The `category` attribute of the `@Plugin` annotation must be set to 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Node.html#CATEGORY[`Node.CATEGORY`]
 (`Core`)
+* The `elementType` attribute of the `@Plugin` annotation must be configured, 
if it belongs under a certain category of elements (appenders, layouts, etc.)
+* It must have a xref:declare-plugin-factory[plugin factory]
+
+See 
{project-github-url}/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayout.java[`JsonTemplateLayout.java`]
 for following details:
+
+* Layout's `@Plugin` annotation sets `category` and `elementType` to 
`Node.CATEGORY` and 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/Layout.html#ELEMENT_TYPE[`Layout.ELEMENT_TYPE`],
 respectively
+* All plugin declarations are provided with a 
`@PluginBuilderFactory`-annotated static method
+* ``EventTemplateAdditionalField`` class' `@Plugin` annotation doesn't have an 
`elementType` attribute, even though it maps to a configuration file element
+
+[#declare-plugin-factory]
+=== Declaring plugin factories
+
+A *plugin factory* is responsible for
+
+* Creating an instance of the plugin
+* Receiving values (`Configuration` instance, configuration attributes, etc.) 
available in the context
+
+Every plugin that needs to be represented by an element in a configuration 
file must declare a plugin factory using one of the following:
+
+a 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/PluginFactory.html[`@PluginFactory`]-annotated
 static method::
+What is expected to be received is modelled as method arguments.
+Intended for simple plugins that receive less than a handful of values.
++
+See 
{project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/CsvParameterLayout.java[`CsvParameterLayout.java`]
 for an example on `@PluginFactory` usage.
+
+a 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/PluginBuilderFactory.html[`@PluginBuilderFactory`]-annotated
 static method of return type 
link:../javadoc/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Builder.java[`Builder<T>`]::
+What is expected to be received is modelled as fields of a builder class.
+Intended for more sophisticated wiring needs.
++
+.Click for advantages of builder class over factory method
+[%collapsible]
+====
+* Attribute names don't need to be specified, if they match the field name
+* Default values can be specified in code rather than through an annotation.
+This also allows a runtime-calculated default value, which isn't allowed in 
annotations.
+* Default values are specified via code rather than relying on reflection and 
injection, so they work programmatically as well as in a configuration file.
+* Adding new optional parameters doesn't require existing programmatic 
configuration to be refactored.
+* Easier to write unit tests using builders rather than factory methods with 
optional parameters.
+====
++
+See 
{project-github-url}/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayout.java[`JsonTemplateLayout.java`]
 for an example on `@PluginBuilderFactory` usage.
+
+If a plugin class implements `Collection` or `Map`, then no factory method is 
used.
+Instead, the class is instantiated using the default constructor, and all 
child configuration nodes are added to the `Collection` or `Map`.
+
+[#attribute-types]
+==== Plugin factory attribute types
+
+To allow the current `Configuration` to populate the correct arguments for the 
`@PluginFactory`-annotated method (or fields for the builder class), every 
argument to the method must be annotated using one of the following attribute 
types.
+
+link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/PluginAliases.html[`@PluginAliases`]::
+Identifies a list of aliases for a `@Plugin`, `@PluginAttribute`, or 
`@PluginBuilderAttribute`
 
-In Log4j 2 a plugin is declared by adding a 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/Plugin.html[`@Plugin`]
 annotation to the class declaration. During initialization the 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Configuration.html[`Configuration`]
 will invoke the 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/util/PluginManager.html[`PluginManager`]
 to load the built-in Log4j plugins as well as any custom plug [...]
+link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/PluginAttribute.html[`@PluginAttribute`]::
+Denotes a configuration element attribute.
+The parameter must be convertible from a `String` using a `TypeConverter`.
+Most built-in types are already supported, but custom `TypeConverter` plugins 
may also be provided for more type support.
+Note that `PluginBuilderAttribute` can be used in builder class fields as an 
easier way to provide default values.
 
-1. Serialized plugin listing files on the classpath. These files are generated 
automatically during the build (more details below).
-2. (OSGi only) Serialized plugin listing files in each active OSGi bundle. A 
`BundleListener` is added on activation to continue checking new bundles after 
`log4j-core` has started.
-3. **(Deprecated)** A comma-separated list of packages specified by the 
`log4j.plugin.packages` system property.
-4. **(Deprecated)** Packages passed to the static `PluginManager.addPackages` 
method (before Log4j configuration occurs).
-5. **(Deprecated)** The [packages](./configuration.html#ConfigurationSyntax) 
declared in your log4j2 configuration file.
+link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/PluginConfiguration.html[`@PluginConfiguration`]::
+The current `Configuration` object will be passed to the plugin as a parameter.
 
-If multiple Plugins specify the same (case-insensitive) `name`, then the load 
order above determines which one will be used. For example, to override the 
`File` plugin which is provided by the built-in `FileAppender` class, you would 
need to place your plugin in a JAR file in the CLASSPATH ahead 
of`log4j-core.jar`. This is not recommended; plugin name collisions will cause 
a warning to be emitted. Note that in an OSGi environment, the order that 
bundles are scanned for plugins generally  [...]
+[[PluginElement]] 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/PluginElement.html[`@PluginElement`]::
+The parameter may represent a complex object that itself has parameters that 
can be configured.
+This also supports injecting an array of elements.
 
-Serialized plugin listing files are generated by an annotation processor 
contained in the log4j-core artifact which will automatically scan your code 
for Log4j 2 plugins and output a metadata file in your processed classes. There 
is nothing extra that needs to be done to enable this; the Java compiler will 
automatically pick up the annotation processor on the class path unless you 
explicitly disable it. In that case, it would be important to add another 
compiler pass to your build proces [...]
+link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/PluginNode.html[`@PluginNode`]::
+The current `Node` being parsed will be passed to the plugin as a parameter.
 
-[source,xml]
+link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/PluginValue.html[`@PluginValue`]::
+The value of the current `Node` or its attribute named `value`.
+
+Each attribute or element annotation must include the name that must be 
present in the configuration in order to match the configuration item to its 
respective parameter.
+For plugin builders, the names of the fields will be used by default if no 
name is specified in the annotation.
+
+[#type-converters]
+=== Plugin factory attribute type converters
+
+link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/convert/TypeConverter.html[`TypeConverter`]s
 are a certain group of plugins for converting ``String``s read from 
configuration file elements into the types used in plugin factory attributes.
+Other plugins can already be injected via xref:#PluginElement[the 
`@PluginElement` annotation]; now, any type supported by ``TypeConverter``s can 
be used in a `@PluginAttribute`-annotated factory attribute.
+
+Conversion of enum types are supported on demand and do not require custom 
``TypeConverter``s.
+A large number of built-in Java classes (`int`, `long`, `BigDecimal`, etc.) 
are already supported; see 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/convert/TypeConverters.html[`TypeConverters`]
 for a more exhaustive listing.
+
+You can create custom ``TypeConverter``s as follows:
+
+* Extend from 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/convert/TypeConverter.html[the
 `TypeConverter` interface]
+
+* Set the `category` attribute of the `@Plugin` annotation to 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/convert/TypeConverters.html#CATEGORY[`TypeConverters.CATEGORY`]
 (`TypeConverter`).
+Unlike other plugins, the plugin name of a `TypeConverter` is purely cosmetic.
+
+* Have a default constructor
+
+* Optionally, extend from `Comparable<TypeConverter<?>>`, which will be used 
for determining the order in case of multiple `TypeConverter` candidates for a 
certain type
+
+See 
{project-github-url}/log4j-core/org/apache/logging/log4j/core/config/plugins/convert/TypeConverters.java[`TypeConverters.java`]
 for example implementations.
+
+[#constraint-validators]
+==== Plugin factory attribute validators
+
+Plugin factory fields and parameters can be automatically validated at runtime 
using constraint validators inspired by https://beanvalidation.org[Bean 
Validation].
+The following annotations are bundled in Log4j, but custom 
``ConstraintValidator`` can be created as well.
+
+link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/validation/constraints/Required.html[`@Required`]::
+This annotation validates that a value is non-empty.
+This covers a check for null as well as several other scenarios: empty 
`CharSequence` objects, empty arrays, empty `Collection` instances, and empty 
`Map` instances.
+
+link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/validation/constraints/ValidHost.html[`@ValidHost`]::
+This annotation validates that a value corresponds to a valid host name.
+This uses the same validation as 
https://docs.oracle.com/javase/{java-target-version}/docs/api/java/net/InetAddress.html#getByName-java.lang.String-[`InetAddress.getByName(String)`].
+
+link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/validation/constraints/ValidPort.html[`@ValidPort`]::
+This annotation validates that a value corresponds to a valid port number 
between 0 and 65535.
+
+[#plugin-registry]
+== Registering plugins
+
+Registering plugins are done by placing a *Log4j plugin descriptor* (i.e., 
`Log4j2Plugins.dat`) into the classpath.
+This file is generated using the 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/processor/PluginProcessor.html[`PluginProcessor`]
 annotation processor at compile-time.
+You need to configure your build tool as follows to employ `PluginProcessor` 
by the Java compiler:
+
+[tabs]
+====
+Maven::
++
+[source,xml,subs="+attributes"]
 ----
 <plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-compiler-plugin</artifactId>
-  <version>3.1</version>
+  <version>${maven-compiler-plugin.version}</version>
   <executions>
     <execution>
-      <id>log4j-plugin-processor</id>
+      <id>generate-log4j-plugin-descriptor</id>
       <goals>
         <goal>compile</goal>
       </goals>
       <phase>process-classes</phase>
       <configuration>
         <proc>only</proc>
+        <annotationProcessorPaths>
+          <!-- Include `log4j-core` providing 
`org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor` that 
generates `Log4j2Plugins.dat` -->
+          <path>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-core</artifactId>
+            <version>{log4j-core-version}</version>
+          </path>
+        </annotationProcessorPaths>
         <annotationProcessors>
-          
<annotationProcessor>org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor</annotationProcessor>
+          <!-- Process sources using 
`org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor` to 
generate `Log4j2Plugins.dat` -->
+          
<processor>org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor</processor>
         </annotationProcessors>
       </configuration>
     </execution>
@@ -54,48 +242,44 @@ Serialized plugin listing files are generated by an 
annotation processor contain
 </plugin>
 ----
 
-[#core]
-== Core
-Core plugins are those that are directly represented by an element in a 
configuration file, such as an Appender, Layout, Logger or Filter. Custom 
plugins that conform to the rules laid out in the next paragraph may simply be 
referenced in the configuration, provided they are appropriate configured to be 
loaded by the PluginManager.
-
-Every Core plugin must declare a static method annotated with @PluginFactory 
or @PluginBuilderFactory. The former is used for static factory methods that 
provide all options as method parameters, and the latter is used to construct a 
new Builder<T> class whose fields are used for injecting attributes and child 
nodes. To allow the Configuration to pass the correct parameters to the method, 
every parameter to the method must be annotated as one of the following 
attribute types. Each attrib [...]
-
-[#attribute-types]
-=== Attribute types
-
-* PluginAttribute: The parameter must be convertible from a String using a 
TypeConverter. Most built-in types are already supported, but custom 
TypeConverter plugins may also be provided for more type support. Note that 
PluginBuilderAttribute can be used in builder class fields as an easier way to 
provide default values.
-* PluginElement: The parameter may represent a complex object that itself has 
parameters that can be configured. This also supports injecting an array of 
elements.
-* PluginConfiguration: The current Configuration object will be passed to the 
plugin as a parameter.
-* PluginNode: The current Node being parsed will be passed to the plugin as a 
parameter.
-* PluginValue: The value of the current Node or its attribute named value.
-
-[#constraint-validators]
-=== Constraint validators
+Gradle::
++
+[source,groovy,subs="+attributes"]
+----
+dependencies {
+  // Process sources using `log4j-core` providing 
`org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor` that 
generates `Log4j2Plugins.dat` -->
+  
annotationProcessor('org.apache.logging.log4j:log4j-core:{log4j-core-version}')
+}
+----
+====
 
-Plugin factory fields and parameters can be automatically validated at runtime 
using constraint validators inspired by the Bean Validation spec. The following 
annotations are bundled in Log4j, but custom ConstraintValidators can be 
created as well.
+[#plugin-discovery]
+== Discovering plugins
 
-* Required: This annotation validates that a value is non-empty. This covers a 
check for null as well as several other scenarios: empty CharSequence objects, 
empty arrays, empty Collection instances, and empty Map instances.
-* ValidHost: This annotation validates that a value corresponds to a valid 
hostname. This uses the same validation as InetAddress::getByName.
-* ValidPort: This annotation validates that a value corresponds to a valid 
port number between 0 and 65535.
+link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/util/PluginManager.html[`PluginManager`]
 is responsible for discovering plugins and loading their descriptions.
+It locates plugins by looking in following places in given order:
 
-[#key-providers]
-== Key providers
+. Plugin descriptor files on the classpath.
+These files are generated automatically at compile-time by the Log4j plugin 
annotation processor.
+See <<plugin-registry>> for details.
 
-Some components within Log4j may provide the ability to perform data 
encryption. These components require a secret key to perform the encryption. 
Applications may provide the key by creating a class that implements the 
SecretKeyProvider interface.
+. *[OSGi only]* Serialized plugin listing files in each active OSGi bundle.
+A `BundleListener` is added on activation to continue checking new bundles 
after Log4j Core has started.
 
-[#lookups]
-== Lookups
+. *[Deprecated]* A comma-separated list of packages specified by the 
`log4j.plugin.packages` system property
 
-Lookups are perhaps the simplest plugins of all. They must declare their type 
as "Lookup" on the plugin annotation and must implement the StrLookup 
interface. They will have two methods; a lookup method that accepts a String 
key and returns a String value and a second lookup method that accepts both a 
LogEvent and a String key and returns a String. Lookups may be referenced by 
specifying ${name:key} where name is the name specified in the Plugin 
annotation and key is the name of the item [...]
+. *[Deprecated]* Packages passed to the static `PluginManager.addPackages()` 
method before Log4j configuration takes place
 
-[#type-converters]
-== Type converters
+. *[Deprecated]* The `packages` attribute declared at the root element of your 
Log4j configuration file
 
-TypeConverters are a sort of meta-plugin used for converting strings into 
other types in a plugin factory method parameter. Other plugins can already be 
injected via the @PluginElement annotation; now, any type supported by the type 
conversion system can be used in a @PluginAttribute parameter. Conversion of 
enum types are supported on demand and do not require custom TypeConverter 
classes. A large number of built-in Java classes are already supported; see 
TypeConverters for a more exhau [...]
+[#plugin-load]
+== Loading plugins
 
-Unlike other plugins, the plugin name of a TypeConverter is purely cosmetic. 
Appropriate type converters are looked up via the Type interface rather than 
via Class<?> objects only. Do note that TypeConverter plugins must have a 
default constructor. When multiple converters match for a type, the first will 
be returned. If any extends from Comparable<TypeConverter<?>>, it will be used 
for determining the order.
+It is pretty common that a plugin uses other plugins; appenders accept 
layouts, some layouts accept key-value pairs, etc.
+You can do this as follows:
 
-[#developer-notes]
-==  Developer notes
+* If your plugin has a <<#declare-plugin-factory,plugin factory>> (i.e., it is 
represented by a configuration file element), you can use <<#PluginElement, the 
`@PluginElement` annotation>> to receive other plugins.
+See `@PluginElement("EventTemplateAdditionalField")` usage in 
{project-github-url}/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayout.java[`JsonTemplateLayout.java`]
 for an example.
 
-If a plugin class implements Collection or Map, then no factory method is 
used. Instead, the class is instantiated using the default constructor, and all 
child configuration nodes are added to the Collection or Map.
+* Otherwise, you can use 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/util/PluginUtl.html[`PluginUtil`],
 which is a convenient wrapper around <<#plugin-discovery,`PluginManager`>>, to 
discover and load plugins.
+See 
{project-github-url}/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/TemplateResolverFactories.java[`TemplateResolverFactories.java`]
 for example usages.
diff --git a/src/site/resources/.htaccess b/src/site/resources/.htaccess
index 6bef5ba191..a96bb00fa1 100644
--- a/src/site/resources/.htaccess
+++ b/src/site/resources/.htaccess
@@ -59,6 +59,7 @@ RewriteRule "^manual/extending\.html#Filters$" 
"manual/filters.html#extending" [
 RewriteRule "^manual/extending\.html#Layouts$" "manual/layouts.html#extending" 
[R=permanent]
 RewriteRule "^manual/extending\.html#Lookups$" "manual/lookups.html#extending" 
[R=permanent]
 RewriteRule "^manual/extending\.html#PatternConverters$" 
"manual/pattern-layout.html#extending-converters" [R=permanent]
+RewriteRule "^manual/extending\.html#Plugin_Builders$" 
"manual/plugins.html#declare-plugin-factory" [R=permanent]
 RewriteRule "^manual/layouts\.html#enable-jansi$" 
"manual/pattern-layout.html#jansi" [R=permanent]
 RewriteRule "^manual/layouts\.html#EndOfBatch$" 
"manual/pattern-layout.html#converter-end-of-batch" [R=permanent]
 RewriteRule "^manual/layouts\.html#LevelPatternSelector$" 
"manual/pattern-layout.html#plugin-element-LevelPatternSelector" [R=permanent]
@@ -98,6 +99,8 @@ RewriteRule "^manual/layouts\.html#Process_ID$" 
"manual/pattern-layout.html#conv
 RewriteRule "^manual/layouts\.html#ScriptPatternSelector$" 
"manual/pattern-layout.html#plugin-element-ScriptPatternSelector" [R=permanent]
 RewriteRule "^manual/layouts\.html#VariablesNotEmpty$" 
"manual/pattern-layout.html#converter-not-empty" [R=permanent]
 RewriteRule "^manual/plugins\.html#converters$" 
"manual/pattern-layout.html#extending-converters" [R=permanent]
+RewriteRule "^manual/plugins\.html#developer-notes$" "manual/plugins.html" 
[R=permanent]
+RewriteRule "^manual/plugins\.html#lookups$" "manual/lookups.html#extending" 
[R=permanent]
 RewriteRule "^manual/scala-api\.html$" "/log4j/scala/latest/index.html" 
[R=permanent]
 RewriteRule "^manual/usage\.html$" "manual/api.html" [R=permanent]
 RewriteRule "^runtime-dependencies\.html$" "manual/installation.html" 
[R=permanent]

Reply via email to