You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ma...@apache.org on 2022/01/02 01:08:12 UTC
[logging-log4j2] branch master updated (69398f2 -> a7ca777)
This is an automated email from the ASF dual-hosted git repository.
mattsicker pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git.
from 69398f2 Port from release-2.x, can't cherry-pick thanks to jpms.
add 2344d35 Add v3 annotation API
add bc2e767 Add v3 dependency injection SPI
add 379234d Add v3 dependency injection default implementation and tests
add 1ed2584 Add missing class
add 6dc0812 Use weak cache for type closure lookup
add cb9c012 Refactor cache API
add a827c77 Refactor Collection<Qualifier> into own class
add d537be3 Simplify disposer method type matching
add bb256a7 Extract internal code into SPI interface
add 7906e63 Combine scoped and bean packages and other docs
add b4d7cfc Merge Scoped into Bean
add 5e17845 Clean up initialization context usage in bean runner
add 3aeec75 Remove BeanInstance class
add 03be319 Remove stereotypes
add 37e122b Simplify InjectionFactory into Injector
add 4bcdc58 Update exceptions
add b72de60 Simplify producer code and optimizations
add 5f86788 Merge branch 'master' into mean-bean-machine
add 0184771 Remove unused method and rename
add eba9421 Add support for default @Named value
add e255f43 Improve toString representation
add 915a659 Use decapitalized simple class name for default @Named value
add 3a6fee3 Use better exception type
add f089940 Remove unused type parameter in Variable
add a11f179 Use better exceptions
add e9c1233 Decrease visibility
add 41f31dd Improve toString
add 37aacb1 Remove unused import
add 0fe2003 Improve annotation meta-modeling
add b95c818 Remove unused type parameters
add 41b8043 Add variable withers
add b228c68 Removed unused methods
add aaccfb9 Use normalized internal state for qualifers
add a3d7805 Rename scope annotations to use Scoped suffix
add 9043b20 Add tests around deferred instantiation
add 546ab29 Make test more explicit
add 5138f52 Split bean loading and validation
add a7fbac6 Clean up use of Variable
add f135d48 Make behavior match updated docs
add 60cc78c Avoid LoD violations
add 20f23a7 Remove redundant instanceof
add 5031dd6 Remove unneeded methods
add 0770786 Specify targets for scopes
add 7f8995b Rearrange code for clarity
add 4e7b905 Extract ProviderFactory interface
add 5c2aa2f Merge branch 'master' into mean-bean-machine
add 5ae774a Inline Qualifiers
add 65e0d87 Remove unused class
add 45306c2 Merge remote-tracking branch 'origin/master' into mean-bean-machine
add b381d8d Merge branch 'master' into mean-bean-machine
add 221b364 Merge branch 'master' into mean-bean-machine
add 78e1f10 Replace java.beans use with BeanUtils
add 788da26 Merge branch 'master' into mean-bean-machine
add 317969f Merge branch 'master' into mean-bean-machine
add c83c9a1 Move DI SPI to log4j-core
add cd461f1 Add more DI API docs with some renames
add 79561f8 Add more DI API docs
add f7ea16e Simplify reflection model and qualifiers matching
add 9eb91f9 Merge branch 'master' into mean-bean-machine
add 6caab9e Clean up BeanManager API surface
add a789af3 Add tests and stable ordering for bean inheritance
add c7dc660 Merge branch 'master' into mean-bean-machine
add c4b8807 Merge branch 'master' into mean-bean-machine
add 9efae8a Merge branch 'master' into mean-bean-machine
add 64f8151 Fix compile warning
add 8000a00 Improve docs
add 7ff8c9c Add foundation for bean annotation processing and plugin metadata
add b4545a4 Add LoggerContextScoped annotation
add c3c88f5 Add type hierarchy data to plugin modules
add 2d3e8f0 Use proper producer annotation for bridging APIs
add 1e33a72 Check for scope of bean class as fallback
add 4bf8c3e Add richer plugin bean metadata generation
new a7ca777 Merge branch 'mean-bean-machine'
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../java/org/apache/logging/log4j/LoggerTest.java | 2 +-
.../logging/log4j/NoopThreadContextTest.java | 2 +
.../log4j/core/config/di/BeanManagerTest.java | 605 +++++++++++++++++++++
.../log4j/core/config/di/InjectionPointTest.java | 136 +++++
.../log4j/core/config/di/InjectionTargetTest.java | 109 ++++
log4j-core-test/src/test/java9/module-info.java | 2 +
log4j-core/src/main/java/module-info.java | 2 +
.../core/config/di/AmbiguousBeanException.java | 12 +-
.../apache/logging/log4j/core/config/di/Bean.java | 98 ++++
.../logging/log4j/core/config/di/BeanManager.java | 265 +++++++++
.../log4j/core/config/di/DefinitionException.java | 10 +-
.../core/config/di/IllegalProductException.java | 10 +-
.../core/config/di/InitializationContext.java | 54 ++
.../core/config/di/InitializationException.java | 10 +-
.../log4j/core/config/di/InjectionException.java | 14 +-
.../log4j/core/config/di/InjectionPoint.java | 55 ++
.../log4j/core/config/di/InjectionTarget.java | 63 +++
.../core/config/di/InjectionTargetFactory.java | 8 +-
.../LoggerContextScoped.java} | 21 +-
.../logging/log4j/core/config/di/Producer.java | 67 +++
.../log4j/core/config/di/ProducerFactory.java | 9 +-
.../log4j/core/config/di/ResolutionException.java | 10 +-
.../logging/log4j/core/config/di/ScopeContext.java | 63 +++
.../core/config/di/UnsatisfiedBeanException.java | 18 +-
.../log4j/core/config/di/ValidationException.java | 25 +-
.../log4j/core/config/di/impl/AbstractBean.java | 76 +++
.../core/config/di/impl/AbstractProducer.java | 74 +++
.../config/di/impl/AbstractProducerFactory.java | 42 ++
.../core/config/di/impl/DefaultBeanManager.java | 460 ++++++++++++++++
.../di/impl/DefaultInitializationContext.java | 134 +++++
.../core/config/di/impl/DefaultInjectionPoint.java | 121 +++++
.../config/di/impl/DefaultInjectionTarget.java | 136 +++++
.../di/impl/DefaultInjectionTargetFactory.java | 160 ++++++
.../core/config/di/impl/DefaultScopeContext.java | 72 +++
.../core/config/di/impl/DependentScopeContext.java | 58 ++
.../log4j/core/config/di/impl/FieldProducer.java | 67 +++
.../core/config/di/impl/FieldProducerFactory.java | 44 ++
.../core/config/di/impl/InjectionTargetBean.java | 86 +++
.../log4j/core/config/di/impl/Injector.java | 111 ++++
.../log4j/core/config/di/impl/MethodProducer.java | 63 +++
.../core/config/di/impl/MethodProducerFactory.java | 47 ++
.../log4j/core/config/di/impl/OptionalBean.java | 83 +++
.../log4j/core/config/di/impl/ProducerBean.java | 94 ++++
.../log4j/core/config/di/impl/ProvidedBean.java | 77 +++
.../log4j/core/config/di/impl/ProviderBean.java | 77 +++
.../log4j/core/config/plugins/PluginAliases.java | 10 +-
.../log4j/core/config/plugins/PluginAttribute.java | 5 +
.../config/plugins/PluginBuilderAttribute.java | 5 +
.../core/config/plugins/PluginBuilderFactory.java | 9 +-
.../core/config/plugins/PluginConfiguration.java | 2 +
.../log4j/core/config/plugins/PluginElement.java | 5 +
.../log4j/core/config/plugins/PluginFactory.java | 9 +-
.../log4j/core/config/plugins/PluginNode.java | 2 +
.../log4j/core/config/plugins/PluginValue.java | 5 +
.../config/plugins/util/PluginAliasesProvider.java | 20 +-
.../plugins/util/PluginAttributeNameProvider.java | 20 +-
.../util/PluginBuilderAttributeNameProvider.java | 20 +-
.../plugins/util/PluginElementNameProvider.java | 20 +-
.../plugins/util/PluginValueNameProvider.java | 20 +-
.../log4j/plugin/processor/BeanProcessor.java | 516 ++++++++++++++++++
.../log4j/plugin/processor/PluginProcessor.java | 15 +-
.../src/main/java9/module-info.java | 4 +-
.../services/javax.annotation.processing.Processor | 1 +
log4j-plugins-test/pom.xml | 8 +
.../plugins/test/validation/ExampleBean.java} | 34 +-
.../log4j/plugins/test/validation}/FakePlugin.java | 2 +-
.../plugins/test/validation/ImplicitBean.java} | 33 +-
.../test/validation/ImplicitMethodBean.java} | 42 +-
.../plugins/test/validation/ProductionBean.java | 56 ++
log4j-plugins-test/src/main/java9/module-info.java | 1 +
.../log4j/plugin/processor/BeanProcessorTest.java | 51 ++
.../plugin/processor/PluginProcessorTest.java | 9 +-
.../plugins/convert/TypeConverterRegistryTest.java | 10 +-
log4j-plugins/src/main/java/module-info.java | 4 +-
.../org/apache/logging/log4j/plugins/Plugin.java | 3 +
.../logging/log4j/plugins/PluginAliases.java | 6 +
.../logging/log4j/plugins/PluginAttribute.java | 2 +
.../log4j/plugins/PluginBuilderAttribute.java | 2 +
.../logging/log4j/plugins/PluginElement.java | 2 +
.../logging/log4j/plugins/PluginFactory.java | 3 +
.../apache/logging/log4j/plugins/PluginNode.java | 2 +
.../apache/logging/log4j/plugins/PluginValue.java | 2 +
.../logging/log4j/plugins/di/DependentScoped.java | 27 +-
.../plugins/{PluginNode.java => di/Disposes.java} | 20 +-
.../apache/logging/log4j/plugins/di/Inject.java | 51 ++
.../org/apache/logging/log4j/plugins/di/Named.java | 26 +-
.../{PluginAliases.java => di/NamedAliases.java} | 25 +-
.../logging/log4j/plugins/di/PostConstruct.java | 18 +-
.../logging/log4j/plugins/di/PreDestroy.java | 16 +-
.../apache/logging/log4j/plugins/di/Producer.java | 19 +-
.../apache/logging/log4j/plugins/di/Produces.java | 53 ++
.../apache/logging/log4j/plugins/di/Provider.java | 8 +-
.../apache/logging/log4j/plugins/di/Qualifier.java | 19 +-
.../apache/logging/log4j/plugins/di/ScopeType.java | 21 +-
.../logging/log4j/plugins/di/SingletonScoped.java | 19 +-
.../log4j/plugins/di/model/DisposesMethod.java | 53 ++
.../log4j/plugins/di/model/GenericPlugin.java | 35 +-
.../log4j/plugins/di/model/InjectionTarget.java | 49 ++
.../log4j/plugins/di/model/PluginModule.java | 18 +-
.../log4j/plugins/di/model/PluginSource.java | 15 +-
.../log4j/plugins/di/model/ProducerField.java | 55 ++
.../log4j/plugins/di/model/ProducerMethod.java | 62 +++
.../logging/log4j/plugins/di/package-info.java | 15 +-
.../inject/AbstractConfigurationInjector.java | 8 +-
.../log4j/plugins/name/AliasesProvider.java | 16 +-
.../name/AnnotatedElementAliasesProvider.java | 46 ++
.../plugins/name/AnnotatedElementNameProvider.java | 56 +-
.../log4j/plugins/name/NamedAliasesProvider.java | 54 ++
.../plugins/name/NamedQualifierNameProvider.java | 19 +-
.../log4j/plugins/name/PluginAliasesProvider.java | 17 +-
.../log4j/plugins/name/PluginNameProvider.java | 16 +-
.../log4j/plugins/processor/PluginService.java | 4 +-
.../logging/log4j/plugins/util/AnnotationUtil.java | 25 +-
.../apache/logging/log4j/plugins/util/Cache.java | 11 +-
.../logging/log4j/plugins/util/LazyValue.java | 64 +++
.../log4j/plugins/util/ParameterizedTypeImpl.java | 67 +++
.../logging/log4j/plugins/util/TypeUtil.java | 355 +++++++++++-
.../apache/logging/log4j/plugins/util/Value.java | 11 +-
.../logging/log4j/plugins/util/WeakCache.java | 60 ++
.../logging/log4j/plugins/util/WeakLazyValue.java | 58 ++
120 files changed, 5798 insertions(+), 425 deletions(-)
create mode 100644 log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/di/BeanManagerTest.java
create mode 100644 log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/di/InjectionPointTest.java
create mode 100644 log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/di/InjectionTargetTest.java
copy log4j-plugins-test/src/main/java9/module-info.java => log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/AmbiguousBeanException.java (70%)
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/Bean.java
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/BeanManager.java
copy log4j-plugins-test/src/main/java9/module-info.java => log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/DefinitionException.java (70%)
copy log4j-plugins-test/src/main/java9/module-info.java => log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/IllegalProductException.java (70%)
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/InitializationContext.java
copy log4j-plugins-test/src/main/java9/module-info.java => log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/InitializationException.java (70%)
copy log4j-plugins-test/src/main/java9/module-info.java => log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/InjectionException.java (70%)
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/InjectionPoint.java
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/InjectionTarget.java
copy log4j-plugins-test/src/main/java9/module-info.java => log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/InjectionTargetFactory.java (70%)
copy log4j-core/src/main/java/org/apache/logging/log4j/core/config/{plugins/PluginNode.java => di/LoggerContextScoped.java} (68%)
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/Producer.java
copy log4j-plugins-test/src/main/java9/module-info.java => log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/ProducerFactory.java (70%)
copy log4j-plugins-test/src/main/java9/module-info.java => log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/ResolutionException.java (70%)
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/ScopeContext.java
copy log4j-plugin-processor/src/main/java9/module-info.java => log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/UnsatisfiedBeanException.java (67%)
copy log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/processor/FakePlugin.java => log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/ValidationException.java (50%)
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/impl/AbstractBean.java
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/impl/AbstractProducer.java
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/impl/AbstractProducerFactory.java
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/impl/DefaultBeanManager.java
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/impl/DefaultInitializationContext.java
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/impl/DefaultInjectionPoint.java
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/impl/DefaultInjectionTarget.java
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/impl/DefaultInjectionTargetFactory.java
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/impl/DefaultScopeContext.java
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/impl/DependentScopeContext.java
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/impl/FieldProducer.java
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/impl/FieldProducerFactory.java
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/impl/InjectionTargetBean.java
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/impl/Injector.java
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/impl/MethodProducer.java
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/impl/MethodProducerFactory.java
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/impl/OptionalBean.java
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/impl/ProducerBean.java
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/impl/ProvidedBean.java
create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/config/di/impl/ProviderBean.java
copy log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/processor/FakePlugin.java => log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginAliasesProvider.java (62%)
copy log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/processor/FakePlugin.java => log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginAttributeNameProvider.java (60%)
copy log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/processor/FakePlugin.java => log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginBuilderAttributeNameProvider.java (59%)
copy log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/processor/FakePlugin.java => log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginElementNameProvider.java (60%)
copy log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/processor/FakePlugin.java => log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginValueNameProvider.java (61%)
create mode 100644 log4j-plugin-processor/src/main/java/org/apache/logging/log4j/plugin/processor/BeanProcessor.java
copy log4j-plugins-test/src/{test/java/org/apache/logging/log4j/plugins/processor/FakePlugin.java => main/java/org/apache/logging/log4j/plugins/test/validation/ExampleBean.java} (56%)
copy log4j-plugins-test/src/{test/java/org/apache/logging/log4j/plugins/processor => main/java/org/apache/logging/log4j/plugins/test/validation}/FakePlugin.java (95%)
copy log4j-plugins-test/src/{test/java/org/apache/logging/log4j/plugins/processor/FakePlugin.java => main/java/org/apache/logging/log4j/plugins/test/validation/ImplicitBean.java} (56%)
copy log4j-plugins-test/src/{test/java/org/apache/logging/log4j/plugins/processor/FakePlugin.java => main/java/org/apache/logging/log4j/plugins/test/validation/ImplicitMethodBean.java} (50%)
create mode 100644 log4j-plugins-test/src/main/java/org/apache/logging/log4j/plugins/test/validation/ProductionBean.java
create mode 100644 log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugin/processor/BeanProcessorTest.java
copy log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginElement.java => log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/DependentScoped.java (55%)
copy log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/{PluginNode.java => di/Disposes.java} (60%)
create mode 100644 log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/Inject.java
copy log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginNode.java => log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/Named.java (63%)
copy log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/{PluginAliases.java => di/NamedAliases.java} (71%)
copy log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginNode.java => log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/PostConstruct.java (68%)
copy log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginNode.java => log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/PreDestroy.java (68%)
copy log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginBuilderFactory.java => log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/Producer.java (71%)
create mode 100644 log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/Produces.java
copy log4j-plugins-test/src/main/java9/module-info.java => log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/Provider.java (70%)
copy log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginBuilderFactory.java => log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/Qualifier.java (71%)
copy log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginNode.java => log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/ScopeType.java (65%)
copy log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginNode.java => log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/SingletonScoped.java (68%)
create mode 100644 log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/model/DisposesMethod.java
copy log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/processor/FakePlugin.java => log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/model/GenericPlugin.java (51%)
create mode 100644 log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/model/InjectionTarget.java
copy log4j-plugins-test/src/main/java9/module-info.java => log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/model/PluginModule.java (68%)
copy log4j-plugins-test/src/main/java9/module-info.java => log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/model/PluginSource.java (70%)
create mode 100644 log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/model/ProducerField.java
create mode 100644 log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/model/ProducerMethod.java
copy log4j-plugins-test/src/main/java9/module-info.java => log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/package-info.java (69%)
copy log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginNode.java => log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/name/AliasesProvider.java (68%)
create mode 100644 log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/name/AnnotatedElementAliasesProvider.java
create mode 100644 log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/name/NamedAliasesProvider.java
copy log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/processor/FakePlugin.java => log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/name/NamedQualifierNameProvider.java (66%)
copy log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/processor/FakePlugin.java => log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/name/PluginAliasesProvider.java (71%)
copy log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/processor/FakePlugin.java => log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/name/PluginNameProvider.java (71%)
rename log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/processor/FakePlugin.java => log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/AnnotationUtil.java (58%)
copy log4j-plugins-test/src/main/java9/module-info.java => log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/Cache.java (70%)
create mode 100644 log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/LazyValue.java
create mode 100644 log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/ParameterizedTypeImpl.java
copy log4j-plugins-test/src/main/java9/module-info.java => log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/Value.java (70%)
create mode 100644 log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/WeakCache.java
create mode 100644 log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/WeakLazyValue.java
[logging-log4j2] 01/01: Merge branch 'mean-bean-machine'
Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
mattsicker pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit a7ca777c74a99f97703676fbfc96773b6400c3c8
Merge: 69398f2 4bf8c3e
Author: Matt Sicker <ma...@apache.org>
AuthorDate: Sat Jan 1 19:07:44 2022 -0600
Merge branch 'mean-bean-machine'
.../java/org/apache/logging/log4j/LoggerTest.java | 2 +-
.../logging/log4j/NoopThreadContextTest.java | 2 +
.../log4j/core/config/di/BeanManagerTest.java | 605 +++++++++++++++++++++
.../log4j/core/config/di/InjectionPointTest.java | 136 +++++
.../log4j/core/config/di/InjectionTargetTest.java | 109 ++++
log4j-core-test/src/test/java9/module-info.java | 2 +
log4j-core/src/main/java/module-info.java | 2 +
.../core/config/di/AmbiguousBeanException.java | 12 +-
.../apache/logging/log4j/core/config/di/Bean.java | 98 ++++
.../logging/log4j/core/config/di/BeanManager.java | 265 +++++++++
.../log4j/core/config/di/DefinitionException.java | 10 +-
.../core/config/di/IllegalProductException.java | 10 +-
.../core/config/di/InitializationContext.java | 54 ++
.../core/config/di/InitializationException.java | 10 +-
.../log4j/core/config/di/InjectionException.java | 14 +-
.../log4j/core/config/di/InjectionPoint.java | 55 ++
.../log4j/core/config/di/InjectionTarget.java | 63 +++
.../core/config/di/InjectionTargetFactory.java | 8 +-
.../LoggerContextScoped.java} | 21 +-
.../logging/log4j/core/config/di/Producer.java | 67 +++
.../log4j/core/config/di/ProducerFactory.java | 9 +-
.../log4j/core/config/di/ResolutionException.java | 10 +-
.../logging/log4j/core/config/di/ScopeContext.java | 63 +++
.../core/config/di/UnsatisfiedBeanException.java | 18 +-
.../log4j/core/config/di/ValidationException.java | 25 +-
.../log4j/core/config/di/impl/AbstractBean.java | 76 +++
.../core/config/di/impl/AbstractProducer.java | 74 +++
.../config/di/impl/AbstractProducerFactory.java | 42 ++
.../core/config/di/impl/DefaultBeanManager.java | 460 ++++++++++++++++
.../di/impl/DefaultInitializationContext.java | 134 +++++
.../core/config/di/impl/DefaultInjectionPoint.java | 121 +++++
.../config/di/impl/DefaultInjectionTarget.java | 136 +++++
.../di/impl/DefaultInjectionTargetFactory.java | 160 ++++++
.../core/config/di/impl/DefaultScopeContext.java | 72 +++
.../core/config/di/impl/DependentScopeContext.java | 58 ++
.../log4j/core/config/di/impl/FieldProducer.java | 67 +++
.../core/config/di/impl/FieldProducerFactory.java | 44 ++
.../core/config/di/impl/InjectionTargetBean.java | 86 +++
.../log4j/core/config/di/impl/Injector.java | 111 ++++
.../log4j/core/config/di/impl/MethodProducer.java | 63 +++
.../core/config/di/impl/MethodProducerFactory.java | 47 ++
.../log4j/core/config/di/impl/OptionalBean.java | 83 +++
.../log4j/core/config/di/impl/ProducerBean.java | 94 ++++
.../log4j/core/config/di/impl/ProvidedBean.java | 77 +++
.../log4j/core/config/di/impl/ProviderBean.java | 77 +++
.../log4j/core/config/plugins/PluginAliases.java | 10 +-
.../log4j/core/config/plugins/PluginAttribute.java | 5 +
.../config/plugins/PluginBuilderAttribute.java | 5 +
.../core/config/plugins/PluginBuilderFactory.java | 9 +-
.../core/config/plugins/PluginConfiguration.java | 2 +
.../log4j/core/config/plugins/PluginElement.java | 5 +
.../log4j/core/config/plugins/PluginFactory.java | 9 +-
.../log4j/core/config/plugins/PluginNode.java | 2 +
.../log4j/core/config/plugins/PluginValue.java | 5 +
.../config/plugins/util/PluginAliasesProvider.java | 20 +-
.../plugins/util/PluginAttributeNameProvider.java | 20 +-
.../util/PluginBuilderAttributeNameProvider.java | 20 +-
.../plugins/util/PluginElementNameProvider.java | 20 +-
.../plugins/util/PluginValueNameProvider.java | 20 +-
.../log4j/plugin/processor/BeanProcessor.java | 516 ++++++++++++++++++
.../log4j/plugin/processor/PluginProcessor.java | 15 +-
.../src/main/java9/module-info.java | 4 +-
.../services/javax.annotation.processing.Processor | 1 +
log4j-plugins-test/pom.xml | 8 +
.../plugins/test/validation/ExampleBean.java} | 34 +-
.../log4j/plugins/test/validation}/FakePlugin.java | 2 +-
.../plugins/test/validation/ImplicitBean.java} | 33 +-
.../test/validation/ImplicitMethodBean.java} | 42 +-
.../plugins/test/validation/ProductionBean.java | 56 ++
log4j-plugins-test/src/main/java9/module-info.java | 1 +
.../log4j/plugin/processor/BeanProcessorTest.java | 51 ++
.../plugin/processor/PluginProcessorTest.java | 9 +-
.../plugins/convert/TypeConverterRegistryTest.java | 10 +-
log4j-plugins/src/main/java/module-info.java | 4 +-
.../org/apache/logging/log4j/plugins/Plugin.java | 3 +
.../logging/log4j/plugins/PluginAliases.java | 6 +
.../logging/log4j/plugins/PluginAttribute.java | 2 +
.../log4j/plugins/PluginBuilderAttribute.java | 2 +
.../logging/log4j/plugins/PluginElement.java | 2 +
.../logging/log4j/plugins/PluginFactory.java | 3 +
.../apache/logging/log4j/plugins/PluginNode.java | 2 +
.../apache/logging/log4j/plugins/PluginValue.java | 2 +
.../logging/log4j/plugins/di/DependentScoped.java | 27 +-
.../plugins/{PluginNode.java => di/Disposes.java} | 20 +-
.../apache/logging/log4j/plugins/di/Inject.java | 51 ++
.../org/apache/logging/log4j/plugins/di/Named.java | 26 +-
.../{PluginAliases.java => di/NamedAliases.java} | 25 +-
.../logging/log4j/plugins/di/PostConstruct.java | 18 +-
.../logging/log4j/plugins/di/PreDestroy.java | 16 +-
.../apache/logging/log4j/plugins/di/Producer.java | 19 +-
.../apache/logging/log4j/plugins/di/Produces.java | 53 ++
.../apache/logging/log4j/plugins/di/Provider.java | 8 +-
.../apache/logging/log4j/plugins/di/Qualifier.java | 19 +-
.../apache/logging/log4j/plugins/di/ScopeType.java | 21 +-
.../logging/log4j/plugins/di/SingletonScoped.java | 19 +-
.../log4j/plugins/di/model/DisposesMethod.java | 53 ++
.../log4j/plugins/di/model/GenericPlugin.java | 35 +-
.../log4j/plugins/di/model/InjectionTarget.java | 49 ++
.../log4j/plugins/di/model/PluginModule.java | 18 +-
.../log4j/plugins/di/model/PluginSource.java | 15 +-
.../log4j/plugins/di/model/ProducerField.java | 55 ++
.../log4j/plugins/di/model/ProducerMethod.java | 62 +++
.../logging/log4j/plugins/di/package-info.java | 15 +-
.../inject/AbstractConfigurationInjector.java | 8 +-
.../log4j/plugins/name/AliasesProvider.java | 16 +-
.../name/AnnotatedElementAliasesProvider.java | 46 ++
.../plugins/name/AnnotatedElementNameProvider.java | 56 +-
.../log4j/plugins/name/NamedAliasesProvider.java | 54 ++
.../plugins/name/NamedQualifierNameProvider.java | 19 +-
.../log4j/plugins/name/PluginAliasesProvider.java | 17 +-
.../log4j/plugins/name/PluginNameProvider.java | 16 +-
.../log4j/plugins/processor/PluginService.java | 4 +-
.../logging/log4j/plugins/util/AnnotationUtil.java | 25 +-
.../apache/logging/log4j/plugins/util/Cache.java | 11 +-
.../logging/log4j/plugins/util/LazyValue.java | 64 +++
.../log4j/plugins/util/ParameterizedTypeImpl.java | 67 +++
.../logging/log4j/plugins/util/TypeUtil.java | 355 +++++++++++-
.../apache/logging/log4j/plugins/util/Value.java | 11 +-
.../logging/log4j/plugins/util/WeakCache.java | 60 ++
.../logging/log4j/plugins/util/WeakLazyValue.java | 58 ++
120 files changed, 5798 insertions(+), 425 deletions(-)
diff --cc log4j-api-test/src/test/java/org/apache/logging/log4j/LoggerTest.java
index d98f0ea,0000000..27a3a8e
mode 100644,000000..100644
--- a/log4j-api-test/src/test/java/org/apache/logging/log4j/LoggerTest.java
+++ b/log4j-api-test/src/test/java/org/apache/logging/log4j/LoggerTest.java
@@@ -1,634 -1,0 +1,634 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j;
+
+import org.apache.logging.log4j.message.EntryMessage;
+import org.apache.logging.log4j.message.JsonMessage;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.message.MessageFactory;
+import org.apache.logging.log4j.message.ObjectMessage;
+import org.apache.logging.log4j.message.ParameterizedMessageFactory;
+import org.apache.logging.log4j.message.SimpleMessage;
+import org.apache.logging.log4j.message.SimpleMessageFactory;
+import org.apache.logging.log4j.message.StringFormatterMessageFactory;
+import org.apache.logging.log4j.message.StructuredDataMessage;
+import org.apache.logging.log4j.test.TestLogger;
+import org.apache.logging.log4j.test.junit.UsingThreadContextMap;
+import org.apache.logging.log4j.util.Strings;
+import org.apache.logging.log4j.util.Supplier;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.parallel.ResourceLock;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Properties;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.*;
+
+@ResourceLock("log4j2.MarkerManager")
+@ResourceLock("log4j2.TestLogger")
+@UsingThreadContextMap
+public class LoggerTest {
+
+ private static class TestParameterizedMessageFactory {
+ // empty
+ }
+
+ private static class TestStringFormatterMessageFactory {
+ // empty
+ }
+
+ private final TestLogger logger = (TestLogger) LogManager.getLogger("LoggerTest");
+ private final Marker marker = MarkerManager.getMarker("test");
+ private final List<String> results = logger.getEntries();
+
+ @Test
+ public void builder() {
+ logger.atDebug().withLocation().log("Hello");
+ logger.atError().withMarker(marker).log("Hello {}", "John");
+ logger.atWarn().withThrowable(new Throwable("This is a test")).log((Message) new SimpleMessage("Log4j rocks!"));
+ assertEquals(3, results.size());
+ assertThat("Incorrect message 1", results.get(0),
+ equalTo(" DEBUG org.apache.logging.log4j.LoggerTest.builder(LoggerTest.java:65) Hello"));
+ assertThat("Incorrect message 2", results.get(1), equalTo("test ERROR Hello John"));
+ assertThat("Incorrect message 3", results.get(2),
+ startsWith(" WARN Log4j rocks! java.lang.Throwable: This is a test"));
+ assertThat("Throwable incorrect in message 3", results.get(2),
+ containsString("org.apache.logging.log4j.LoggerTest.builder(LoggerTest.java:67)"));
+ }
+
+ @Test
+ public void basicFlow() {
+ logger.traceEntry();
+ logger.traceExit();
+ assertEquals(2, results.size());
+ assertThat("Incorrect Entry", results.get(0), equalTo("ENTER[ FLOW ] TRACE Enter"));
+ assertThat("incorrect Exit", results.get(1), equalTo("EXIT[ FLOW ] TRACE Exit"));
+
+ }
+
+ @Test
+ public void flowTracingMessage() {
+ Properties props = new Properties();
+ props.setProperty("foo", "bar");
+ logger.traceEntry(new JsonMessage(props));
+ final Response response = new Response(-1, "Generic error");
+ logger.traceExit(new JsonMessage(response), response);
+ assertEquals(2, results.size());
+ assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));
+ assertThat("Missing entry data", results.get(0), containsString("\"foo\":\"bar\""));
+ assertThat("incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));
+ assertThat("Missing exit data", results.get(1), containsString("\"message\":\"Generic error\""));
+ }
+
+ @Test
+ public void flowTracingString_ObjectArray1() {
+ logger.traceEntry("doFoo(a={}, b={})", 1, 2);
+ logger.traceExit("doFoo(a=1, b=2): {}", 3);
+ assertEquals(2, results.size());
+ assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));
+ assertThat("Missing entry data", results.get(0), containsString("doFoo(a=1, b=2)"));
+ assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));
+ assertThat("Missing exit data", results.get(1), containsString("doFoo(a=1, b=2): 3"));
+ }
+
+ @Test
+ public void flowTracingExitValueOnly() {
+ logger.traceEntry("doFoo(a={}, b={})", 1, 2);
+ logger.traceExit(3);
+ assertEquals(2, results.size());
+ assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));
+ assertThat("Missing entry data", results.get(0), containsString("doFoo(a=1, b=2)"));
+ assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));
+ assertThat("Missing exit data", results.get(1), containsString("3"));
+ }
+
+ @Test
+ public void flowTracingString_ObjectArray2() {
+ final EntryMessage msg = logger.traceEntry("doFoo(a={}, b={})", 1, 2);
+ logger.traceExit(msg, 3);
+ assertEquals(2, results.size());
+ assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));
+ assertThat("Missing entry data", results.get(0), containsString("doFoo(a=1, b=2)"));
+ assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));
+ assertThat("Missing exit data", results.get(1), containsString("doFoo(a=1, b=2): 3"));
+ }
+
+ @Test
+ public void flowTracingVoidReturn() {
+ final EntryMessage msg = logger.traceEntry("doFoo(a={}, b={})", 1, 2);
+ logger.traceExit(msg);
+ assertEquals(2, results.size());
+ assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));
+ assertThat("Missing entry data", results.get(0), containsString("doFoo(a=1, b=2)"));
+ assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));
+ assertThat("Missing exit data", results.get(1), endsWith("doFoo(a=1, b=2)"));
+ }
+
+ @Test
+ public void flowTracingNoExitArgs() {
+ logger.traceEntry();
+ logger.traceExit();
+ assertEquals(2, results.size());
+ assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));
+ assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));
+ }
+
+ @Test
+ public void flowTracingNoArgs() {
+ final EntryMessage message = logger.traceEntry();
+ logger.traceExit(message);
+ assertEquals(2, results.size());
+ assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));
+ assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));
+ }
+
+ @Test
+ public void flowTracingString_SupplierOfObjectMessages() {
+ final EntryMessage msg = logger.traceEntry("doFoo(a={}, b={})", new Supplier<Message>() {
+ @Override
+ public Message get() {
+ return new ObjectMessage(1);
+ }
+ }, new Supplier<Message>() {
+ @Override
+ public Message get() {
+ return new ObjectMessage(2);
+ }
+ });
+ logger.traceExit(msg, 3);
+ assertEquals(2, results.size());
+ assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));
+ assertThat("Missing entry data", results.get(0), containsString("doFoo(a=1, b=2)"));
+ assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));
+ assertThat("Missing exit data", results.get(1), containsString("doFoo(a=1, b=2): 3"));
+ }
+
+ @Test
+ public void flowTracingString_SupplierOfStrings() {
+ final EntryMessage msg = logger.traceEntry("doFoo(a={}, b={})", new Supplier<String>() {
+ @Override
+ public String get() {
+ return "1";
+ }
+ }, new Supplier<String>() {
+ @Override
+ public String get() {
+ return "2";
+ }
+ });
+ logger.traceExit(msg, 3);
+ assertEquals(2, results.size());
+ assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));
+ assertThat("Missing entry data", results.get(0), containsString("doFoo(a=1, b=2)"));
+ assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));
+ assertThat("Missing exit data", results.get(1), containsString("doFoo(a=1, b=2): 3"));
+ }
+
+ @Test
+ public void catching() {
+ try {
+ throw new NullPointerException();
+ } catch (final Exception e) {
+ logger.catching(e);
+ assertEquals(1, results.size());
+ assertThat("Incorrect Catching",
+ results.get(0), startsWith("CATCHING[ EXCEPTION ] ERROR Catching java.lang.NullPointerException"));
+ }
+ }
+
+ @Test
+ public void debug() {
+ logger.debug("Debug message");
+ assertEquals(1, results.size());
+ assertTrue(results.get(0).startsWith(" DEBUG Debug message"), "Incorrect message");
+ }
+
+ @Test
+ public void debugObject() {
+ logger.debug(new Date());
+ assertEquals(1, results.size());
+ assertTrue(results.get(0).length() > 7, "Invalid length");
+ }
+
+ @Test
+ public void debugWithParms() {
+ logger.debug("Hello, {}", "World");
+ assertEquals(1, results.size());
+ assertTrue(results.get(0).startsWith(" DEBUG Hello, World"), "Incorrect substitution");
+ }
+
+ @Test
+ public void debugWithParmsAndThrowable() {
+ logger.debug("Hello, {}", "World", new RuntimeException("Test Exception"));
+ assertEquals(1, results.size());
+ assertTrue(
+ results.get(0).startsWith(" DEBUG Hello, World java.lang.RuntimeException: Test Exception"),
+ "Unexpected results: " + results.get(0));
+ }
+
+ @Test
+ public void getFormatterLogger() {
+ // The TestLogger logger was already created in an instance variable for this class.
+ // The message factory is only used when the logger is created.
+ final TestLogger testLogger = (TestLogger) LogManager.getFormatterLogger();
+ final TestLogger altLogger = (TestLogger) LogManager.getFormatterLogger(getClass());
+ assertEquals(testLogger.getName(), altLogger.getName());
+ assertNotNull(testLogger);
+ assertMessageFactoryInstanceOf(testLogger.getMessageFactory(), StringFormatterMessageFactory.class);
+ assertEqualMessageFactory(StringFormatterMessageFactory.INSTANCE, testLogger);
+ testLogger.debug("%,d", Integer.MAX_VALUE);
+ assertEquals(1, testLogger.getEntries().size());
+ assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+ }
+
+ @Test
+ public void getFormatterLogger_Class() {
+ // The TestLogger logger was already created in an instance variable for this class.
+ // The message factory is only used when the logger is created.
+ final TestLogger testLogger = (TestLogger) LogManager.getFormatterLogger(TestStringFormatterMessageFactory.class);
+ assertNotNull(testLogger);
+ assertMessageFactoryInstanceOf(testLogger.getMessageFactory(), StringFormatterMessageFactory.class);
+ assertEqualMessageFactory(StringFormatterMessageFactory.INSTANCE, testLogger);
+ testLogger.debug("%,d", Integer.MAX_VALUE);
+ assertEquals(1, testLogger.getEntries().size());
+ assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+ }
+
+ private static void assertMessageFactoryInstanceOf(MessageFactory factory, final Class<?> cls) {
+ assertTrue(factory.getClass().isAssignableFrom(cls));
+ }
+
+ @Test
+ public void getFormatterLogger_Object() {
+ // The TestLogger logger was already created in an instance variable for this class.
+ // The message factory is only used when the logger is created.
+ final TestLogger testLogger = (TestLogger) LogManager.getFormatterLogger(new TestStringFormatterMessageFactory());
+ assertNotNull(testLogger);
+ assertMessageFactoryInstanceOf(testLogger.getMessageFactory(), StringFormatterMessageFactory.class);
+ assertEqualMessageFactory(StringFormatterMessageFactory.INSTANCE, testLogger);
+ testLogger.debug("%,d", Integer.MAX_VALUE);
+ assertEquals(1, testLogger.getEntries().size());
+ assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+ }
+
+ @Test
+ public void getFormatterLogger_String() {
+ final StringFormatterMessageFactory messageFactory = StringFormatterMessageFactory.INSTANCE;
+ final TestLogger testLogger = (TestLogger) LogManager.getFormatterLogger("getLogger_String_StringFormatterMessageFactory");
+ assertNotNull(testLogger);
+ assertMessageFactoryInstanceOf(testLogger.getMessageFactory(), StringFormatterMessageFactory.class);
+ assertEqualMessageFactory(messageFactory, testLogger);
+ testLogger.debug("%,d", Integer.MAX_VALUE);
+ assertEquals(1, testLogger.getEntries().size());
+ assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+ }
+
+ @Test
+ public void getLogger_Class_ParameterizedMessageFactory() {
+ // The TestLogger logger was already created in an instance variable for this class.
+ // The message factory is only used when the logger is created.
+ final ParameterizedMessageFactory messageFactory = ParameterizedMessageFactory.INSTANCE;
+ final TestLogger testLogger = (TestLogger) LogManager.getLogger(TestParameterizedMessageFactory.class,
+ messageFactory);
+ assertNotNull(testLogger);
+ assertEqualMessageFactory(messageFactory, testLogger);
+ testLogger.debug("{}", Integer.MAX_VALUE);
+ assertEquals(1, testLogger.getEntries().size());
+ assertEquals(" DEBUG " + Integer.MAX_VALUE, testLogger.getEntries().get(0));
+ }
+
+ @Test
+ public void getLogger_Class_StringFormatterMessageFactory() {
+ // The TestLogger logger was already created in an instance variable for this class.
+ // The message factory is only used when the logger is created.
+ final TestLogger testLogger = (TestLogger) LogManager.getLogger(TestStringFormatterMessageFactory.class,
+ StringFormatterMessageFactory.INSTANCE);
+ assertNotNull(testLogger);
+ assertEqualMessageFactory(StringFormatterMessageFactory.INSTANCE, testLogger);
+ testLogger.debug("%,d", Integer.MAX_VALUE);
+ assertEquals(1, testLogger.getEntries().size());
+ assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+ }
+
+ @Test
+ public void getLogger_Object_ParameterizedMessageFactory() {
+ // The TestLogger logger was already created in an instance variable for this class.
+ // The message factory is only used when the logger is created.
+ final ParameterizedMessageFactory messageFactory = ParameterizedMessageFactory.INSTANCE;
+ final TestLogger testLogger = (TestLogger) LogManager.getLogger(new TestParameterizedMessageFactory(),
+ messageFactory);
+ assertNotNull(testLogger);
+ assertEqualMessageFactory(messageFactory, testLogger);
+ testLogger.debug("{}", Integer.MAX_VALUE);
+ assertEquals(1, testLogger.getEntries().size());
+ assertEquals(" DEBUG " + Integer.MAX_VALUE, testLogger.getEntries().get(0));
+ }
+
+ private void assertEqualMessageFactory(final MessageFactory messageFactory, final TestLogger testLogger) {
+ MessageFactory actual = testLogger.getMessageFactory();
+ assertEquals(messageFactory, actual);
+ }
+
+ @Test
+ public void getLogger_Object_StringFormatterMessageFactory() {
+ // The TestLogger logger was already created in an instance variable for this class.
+ // The message factory is only used when the logger is created.
+ final StringFormatterMessageFactory messageFactory = StringFormatterMessageFactory.INSTANCE;
+ final TestLogger testLogger = (TestLogger) LogManager.getLogger(new TestStringFormatterMessageFactory(),
+ messageFactory);
+ assertNotNull(testLogger);
+ assertEqualMessageFactory(messageFactory, testLogger);
+ testLogger.debug("%,d", Integer.MAX_VALUE);
+ assertEquals(1, testLogger.getEntries().size());
+ assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+ }
+
+ @Test
+ public void getLogger_String_MessageFactoryMismatch() {
+ final StringFormatterMessageFactory messageFactory = StringFormatterMessageFactory.INSTANCE;
+ final TestLogger testLogger = (TestLogger) LogManager.getLogger("getLogger_String_MessageFactoryMismatch",
+ messageFactory);
+ assertNotNull(testLogger);
+ assertEqualMessageFactory(messageFactory, testLogger);
+ final TestLogger testLogger2 = (TestLogger) LogManager.getLogger("getLogger_String_MessageFactoryMismatch",
+ ParameterizedMessageFactory.INSTANCE);
+ assertNotNull(testLogger2);
+ //TODO: How to test?
+ //This test context always creates new loggers, other test context impls I tried fail other tests.
+ //assertEquals(messageFactory, testLogger2.getMessageFactory());
+ testLogger.debug("%,d", Integer.MAX_VALUE);
+ assertEquals(1, testLogger.getEntries().size());
+ assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+ }
+
+ @Test
+ public void getLogger_String_ParameterizedMessageFactory() {
+ final ParameterizedMessageFactory messageFactory = ParameterizedMessageFactory.INSTANCE;
+ final TestLogger testLogger = (TestLogger) LogManager.getLogger("getLogger_String_ParameterizedMessageFactory",
+ messageFactory);
+ assertNotNull(testLogger);
+ assertEqualMessageFactory(messageFactory, testLogger);
+ testLogger.debug("{}", Integer.MAX_VALUE);
+ assertEquals(1, testLogger.getEntries().size());
+ assertEquals(" DEBUG " + Integer.MAX_VALUE, testLogger.getEntries().get(0));
+ }
+
+ @Test
+ public void getLogger_String_SimpleMessageFactory() {
+ final SimpleMessageFactory messageFactory = SimpleMessageFactory.INSTANCE;
+ final TestLogger testLogger = (TestLogger) LogManager.getLogger("getLogger_String_StringFormatterMessageFactory",
+ messageFactory);
+ assertNotNull(testLogger);
+ assertEqualMessageFactory(messageFactory, testLogger);
+ testLogger.debug("{} %,d {foo}", Integer.MAX_VALUE);
+ assertEquals(1, testLogger.getEntries().size());
+ assertEquals(" DEBUG {} %,d {foo}", testLogger.getEntries().get(0));
+ }
+
+ @Test
+ public void getLogger_String_StringFormatterMessageFactory() {
+ final StringFormatterMessageFactory messageFactory = StringFormatterMessageFactory.INSTANCE;
+ final TestLogger testLogger = (TestLogger) LogManager.getLogger("getLogger_String_StringFormatterMessageFactory",
+ messageFactory);
+ assertNotNull(testLogger);
+ assertEqualMessageFactory(messageFactory, testLogger);
+ testLogger.debug("%,d", Integer.MAX_VALUE);
+ assertEquals(1, testLogger.getEntries().size());
+ assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+ }
+
+ @Test
+ public void getLoggerByClass() {
+ final Logger classLogger = LogManager.getLogger(LoggerTest.class);
+ assertNotNull(classLogger);
+ }
+
+ @Test
+ public void getLoggerByNullClass() {
+ // Returns a SimpleLogger
+ assertNotNull(LogManager.getLogger((Class<?>) null));
+ }
+
+ @Test
+ public void getLoggerByNullObject() {
+ // Returns a SimpleLogger
+ assertNotNull(LogManager.getLogger((Object) null));
+ }
+
+ @Test
+ public void getLoggerByNullString() {
+ // Returns a SimpleLogger
+ assertNotNull(LogManager.getLogger((String) null));
+ }
+
+ @Test
+ public void getLoggerByObject() {
+ final Logger classLogger = LogManager.getLogger(this);
+ assertNotNull(classLogger);
+ assertEquals(classLogger, LogManager.getLogger(LoggerTest.class));
+ }
+
+ @Test
+ public void getRootLogger() {
+ assertNotNull(LogManager.getRootLogger());
+ assertNotNull(LogManager.getLogger(Strings.EMPTY));
+ assertNotNull(LogManager.getLogger(LogManager.ROOT_LOGGER_NAME));
+ assertEquals(LogManager.getRootLogger(), LogManager.getLogger(Strings.EMPTY));
+ assertEquals(LogManager.getRootLogger(), LogManager.getLogger(LogManager.ROOT_LOGGER_NAME));
+ }
+
+ @Test
+ public void isAllEnabled() {
+ assertTrue(logger.isEnabled(Level.ALL), "Incorrect level");
+ }
+
+ @Test
+ public void isDebugEnabled() {
+ assertTrue(logger.isDebugEnabled(), "Incorrect level");
+ assertTrue(logger.isEnabled(Level.DEBUG), "Incorrect level");
+ }
+
+ @Test
+ public void isErrorEnabled() {
+ assertTrue(logger.isErrorEnabled(), "Incorrect level");
+ assertTrue(logger.isEnabled(Level.ERROR), "Incorrect level");
+ }
+
+ @Test
+ public void isFatalEnabled() {
+ assertTrue(logger.isFatalEnabled(), "Incorrect level");
+ assertTrue(logger.isEnabled(Level.FATAL), "Incorrect level");
+ }
+
+ @Test
+ public void isInfoEnabled() {
+ assertTrue(logger.isInfoEnabled(), "Incorrect level");
+ assertTrue(logger.isEnabled(Level.INFO), "Incorrect level");
+ }
+
+ @Test
+ public void isOffEnabled() {
+ assertTrue(logger.isEnabled(Level.OFF), "Incorrect level");
+ }
+
+ @Test
+ public void isTraceEnabled() {
+ assertTrue(logger.isTraceEnabled(), "Incorrect level");
+ assertTrue(logger.isEnabled(Level.TRACE), "Incorrect level");
+ }
+
+ @Test
+ public void isWarnEnabled() {
+ assertTrue(logger.isWarnEnabled(), "Incorrect level");
+ assertTrue(logger.isEnabled(Level.WARN), "Incorrect level");
+ }
+
+ @Test
+ public void isAllEnabledWithMarker() {
+ assertTrue(logger.isEnabled(Level.ALL, marker), "Incorrect level");
+ }
+
+ @Test
+ public void isDebugEnabledWithMarker() {
+ assertTrue(logger.isDebugEnabled(marker), "Incorrect level");
+ assertTrue(logger.isEnabled(Level.DEBUG, marker), "Incorrect level");
+ }
+
+ @Test
+ public void isErrorEnabledWithMarker() {
+ assertTrue(logger.isErrorEnabled(marker), "Incorrect level");
+ assertTrue(logger.isEnabled(Level.ERROR, marker), "Incorrect level");
+ }
+
+ @Test
+ public void isFatalEnabledWithMarker() {
+ assertTrue(logger.isFatalEnabled(marker), "Incorrect level");
+ assertTrue(logger.isEnabled(Level.FATAL, marker), "Incorrect level");
+ }
+
+ @Test
+ public void isInfoEnabledWithMarker() {
+ assertTrue(logger.isInfoEnabled(marker), "Incorrect level");
+ assertTrue(logger.isEnabled(Level.INFO, marker), "Incorrect level");
+ }
+
+ @Test
+ public void isOffEnabledWithMarker() {
+ assertTrue(logger.isEnabled(Level.OFF, marker), "Incorrect level");
+ }
+
+ @Test
+ public void isTraceEnabledWithMarker() {
+ assertTrue(logger.isTraceEnabled(marker), "Incorrect level");
+ assertTrue(logger.isEnabled(Level.TRACE, marker), "Incorrect level");
+ }
+
+ @Test
+ public void isWarnEnabledWithMarker() {
+ assertTrue(logger.isWarnEnabled(marker), "Incorrect level");
+ assertTrue(logger.isEnabled(Level.WARN, marker), "Incorrect level");
+ }
+
+ @Test
+ public void mdc() {
- ThreadContext.clearAll();
++ ThreadContext.clearMap();
+ ThreadContext.put("TestYear", Integer.valueOf(2010).toString());
+ logger.debug("Debug message");
+ String testYear = ThreadContext.get("TestYear");
+ assertNotNull(testYear, "Test Year is null");
+ assertEquals("2010", testYear, "Incorrect test year: " + testYear);
+ ThreadContext.clearMap();
+ logger.debug("Debug message");
+ assertEquals(2, results.size());
+ System.out.println("Log line 1: " + results.get(0));
+ System.out.println("log line 2: " + results.get(1));
+ assertTrue(
+ results.get(0).startsWith(" DEBUG Debug message {TestYear=2010}"), "Incorrect MDC: " + results.get(0));
+ assertTrue(
+ results.get(1).startsWith(" DEBUG Debug message"), "MDC not cleared?: " + results.get(1));
+ }
+
+ @Test
+ public void printf() {
+ logger.printf(Level.DEBUG, "Debug message %d", 1);
+ logger.printf(Level.DEBUG, MarkerManager.getMarker("Test"), "Debug message %d", 2);
+ assertEquals(2, results.size());
+ assertThat("Incorrect message", results.get(0), startsWith(" DEBUG Debug message 1"));
+ assertThat("Incorrect message", results.get(1), startsWith("Test DEBUG Debug message 2"));
+ }
+
+ @BeforeEach
+ public void setup() {
+ results.clear();
+ }
+
+ @Test
+ public void structuredData() {
+ ThreadContext.put("loginId", "JohnDoe");
+ ThreadContext.put("ipAddress", "192.168.0.120");
+ ThreadContext.put("locale", Locale.US.getDisplayName());
+ final StructuredDataMessage msg = new StructuredDataMessage("Audit@18060", "Transfer Complete", "Transfer");
+ msg.put("ToAccount", "123456");
+ msg.put("FromAccount", "123457");
+ msg.put("Amount", "200.00");
+ logger.info(MarkerManager.getMarker("EVENT"), msg);
+ ThreadContext.clearMap();
+ assertEquals(1, results.size());
+ assertThat("Incorrect structured data: ", results.get(0), startsWith(
+ "EVENT INFO Transfer [Audit@18060 Amount=\"200.00\" FromAccount=\"123457\" ToAccount=\"123456\"] Transfer Complete"));
+ }
+
+ @Test
+ public void throwing() {
+ logger.throwing(new IllegalArgumentException("Test Exception"));
+ assertEquals(1, results.size());
+ assertThat("Incorrect Throwing",
+ results.get(0), startsWith("THROWING[ EXCEPTION ] ERROR Throwing java.lang.IllegalArgumentException: Test Exception"));
+ }
+
+
+ private static class Response {
+ int status;
+ String message;
+
+ public Response(final int status, final String message) {
+ this.status = status;
+ this.message = message;
+ }
+
+ public int getStatus() {
+ return status;
+ }
+
+ public void setStatus(final int status) {
+ this.status = status;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(final String message) {
+ this.message = message;
+ }
+ }
+}
diff --cc log4j-api-test/src/test/java/org/apache/logging/log4j/NoopThreadContextTest.java
index 5c79106,0000000..6a38598
mode 100644,000000..100644
--- a/log4j-api-test/src/test/java/org/apache/logging/log4j/NoopThreadContextTest.java
+++ b/log4j-api-test/src/test/java/org/apache/logging/log4j/NoopThreadContextTest.java
@@@ -1,59 -1,0 +1,61 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j;
+
++import org.apache.logging.log4j.test.junit.UsingThreadContextMap;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.parallel.ResourceLock;
+import org.junit.jupiter.api.parallel.Resources;
+
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+/**
+ * Tests {@link ThreadContext}.
+ */
+@ResourceLock(Resources.SYSTEM_PROPERTIES)
++@UsingThreadContextMap
+public class NoopThreadContextTest {
+
+ private static final String TRUE = "true";
+ private static final String PROPERY_KEY_ALL = "disableThreadContext";
+ private static final String PROPERY_KEY_MAP = "disableThreadContextMap";
+
+ @BeforeAll
+ public static void before() {
+ System.setProperty(PROPERY_KEY_ALL, TRUE);
+ System.setProperty(PROPERY_KEY_MAP, TRUE);
+ ThreadContext.init();
+ }
+
+ @AfterAll
+ public static void after() {
+ System.clearProperty(PROPERY_KEY_ALL);
+ System.clearProperty(PROPERY_KEY_MAP);
+ ThreadContext.init();
+ }
+
+ @Test
+ public void testNoop() {
+ ThreadContext.put("Test", "Test");
+ final String value = ThreadContext.get("Test");
+ assertNull(value, "value was saved");
+ }
+
+
+}
diff --cc log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/di/BeanManagerTest.java
index 0000000,3f67266..3f67266
mode 000000,100644..100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/di/BeanManagerTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/di/BeanManagerTest.java
diff --cc log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/di/InjectionPointTest.java
index 0000000,60e89e4..60e89e4
mode 000000,100644..100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/di/InjectionPointTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/di/InjectionPointTest.java
diff --cc log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/di/InjectionTargetTest.java
index 0000000,c06d2ad..c06d2ad
mode 000000,100644..100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/di/InjectionTargetTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/di/InjectionTargetTest.java
diff --cc log4j-core-test/src/test/java9/module-info.java
index c427d5c,0000000..d02fec4
mode 100644,000000..100644
--- a/log4j-core-test/src/test/java9/module-info.java
+++ b/log4j-core-test/src/test/java9/module-info.java
@@@ -1,92 -1,0 +1,94 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+open module org.apache.logging.log4j.core {
+ exports org.apache.logging.log4j.core;
+ exports org.apache.logging.log4j.core.appender;
+ exports org.apache.logging.log4j.core.appender.db;
+ exports org.apache.logging.log4j.core.appender.nosql;
+ exports org.apache.logging.log4j.core.appender.rewrite;
+ exports org.apache.logging.log4j.core.appender.rolling;
+ exports org.apache.logging.log4j.core.appender.rolling.action;
+ exports org.apache.logging.log4j.core.appender.routing;
+ exports org.apache.logging.log4j.core.async;
+ exports org.apache.logging.log4j.core.config;
+ exports org.apache.logging.log4j.core.config.arbiters;
+ exports org.apache.logging.log4j.core.config.builder;
++ exports org.apache.logging.log4j.core.config.di;
++ exports org.apache.logging.log4j.core.config.di.impl;
+ exports org.apache.logging.log4j.core.config.plugins;
+ exports org.apache.logging.log4j.core.config.plugins.convert;
+ exports org.apache.logging.log4j.core.config.plugins.util;
+ exports org.apache.logging.log4j.core.config.plugins.validation.validators;
+ exports org.apache.logging.log4j.core.config.properties;
+ exports org.apache.logging.log4j.core.config.xml;
+ exports org.apache.logging.log4j.core.filter;
+ exports org.apache.logging.log4j.core.impl;
+ exports org.apache.logging.log4j.core.jmx;
+ exports org.apache.logging.log4j.core.layout;
+ exports org.apache.logging.log4j.core.lookup;
+ exports org.apache.logging.log4j.core.message;
+ exports org.apache.logging.log4j.core.net;
+ exports org.apache.logging.log4j.core.net.ssl;
+ exports org.apache.logging.log4j.core.parser;
+ exports org.apache.logging.log4j.core.pattern;
+ exports org.apache.logging.log4j.core.script;
+ exports org.apache.logging.log4j.core.selector;
+ exports org.apache.logging.log4j.core.test;
+ exports org.apache.logging.log4j.core.test.appender;
+ exports org.apache.logging.log4j.core.test.hamcrest;
+ exports org.apache.logging.log4j.core.test.junit;
+ exports org.apache.logging.log4j.core.time;
+ exports org.apache.logging.log4j.core.tools;
+ exports org.apache.logging.log4j.core.util;
+
+ requires transitive java.compiler;
+ requires transitive java.desktop;
+ requires transitive java.management;
+ requires transitive java.sql;
+ requires transitive java.rmi;
+ requires transitive java.scripting;
+ requires transitive java.xml;
+ requires transitive org.apache.logging.log4j;
+ requires transitive org.apache.logging.log4j.test;
+ requires transitive org.apache.logging.log4j.plugins;
+ requires transitive org.apache.logging.log4j.plugins.test;
+ requires transitive com.lmax.disruptor;
+ requires transitive org.jctools.core;
+ requires transitive org.osgi.framework;
+ requires transitive com.conversantmedia.disruptor;
+ requires transitive net.bytebuddy;
+ requires com.fasterxml.jackson.core;
+ requires com.fasterxml.jackson.databind;
+ requires transitive com.fasterxml.jackson.dataformat.xml;
+ requires transitive com.fasterxml.jackson.dataformat.yaml;
+ requires transitive org.apache.commons.compress;
+ requires transitive org.fusesource.jansi;
+ requires transitive org.junit.jupiter.api;
+ requires transitive org.junit.jupiter.engine;
+ requires transitive org.junit.jupiter.params;
+ requires transitive org.junit.platform.commons;
+ requires transitive org.junit.platform.engine;
+ requires transitive junit;
+
+ uses org.apache.logging.log4j.core.util.ContextDataProvider;
+ uses org.apache.logging.log4j.core.util.WatchEventService;
+ provides org.apache.logging.log4j.message.ThreadDumpMessage.ThreadInfoFactory with org.apache.logging.log4j.core.message.ExtendedThreadInfoFactory;
+ provides org.apache.logging.log4j.core.util.ContextDataProvider with org.apache.logging.log4j.core.impl.ThreadContextDataProvider;
+ provides org.apache.logging.log4j.spi.Provider with org.apache.logging.log4j.core.impl.Log4jProvider;
+ provides org.apache.logging.log4j.plugins.processor.PluginService with org.apache.logging.log4j.core.plugins.Log4jPlugins,
+ org.apache.logging.log4j.core.test.plugins.Log4jPlugins;
+}
diff --cc log4j-core/src/main/java/module-info.java
index 9133d77,0000000..d4b3d93
mode 100644,000000..100644
--- a/log4j-core/src/main/java/module-info.java
+++ b/log4j-core/src/main/java/module-info.java
@@@ -1,86 -1,0 +1,88 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+module org.apache.logging.log4j.core {
+ exports org.apache.logging.log4j.core;
+ exports org.apache.logging.log4j.core.appender;
+ exports org.apache.logging.log4j.core.appender.db;
+ exports org.apache.logging.log4j.core.appender.nosql;
+ exports org.apache.logging.log4j.core.appender.rewrite;
+ exports org.apache.logging.log4j.core.appender.rolling;
+ exports org.apache.logging.log4j.core.appender.rolling.action;
+ exports org.apache.logging.log4j.core.appender.routing;
+ exports org.apache.logging.log4j.core.async;
+ exports org.apache.logging.log4j.core.config;
+ exports org.apache.logging.log4j.core.config.arbiters;
+ exports org.apache.logging.log4j.core.config.builder.api;
+ exports org.apache.logging.log4j.core.config.builder.impl;
+ exports org.apache.logging.log4j.core.config.composite;
++ exports org.apache.logging.log4j.core.config.di;
++ exports org.apache.logging.log4j.core.config.di.impl;
+ exports org.apache.logging.log4j.core.config.json;
+ exports org.apache.logging.log4j.core.config.plugins;
+ exports org.apache.logging.log4j.core.config.plugins.convert;
+ exports org.apache.logging.log4j.core.config.plugins.inject;
+ exports org.apache.logging.log4j.core.config.plugins.util;
+ exports org.apache.logging.log4j.core.config.plugins.visitors;
+ exports org.apache.logging.log4j.core.config.properties;
+ exports org.apache.logging.log4j.core.config.status;
+ exports org.apache.logging.log4j.core.config.xml;
+ exports org.apache.logging.log4j.core.config.yaml;
+ exports org.apache.logging.log4j.core.filter;
+ exports org.apache.logging.log4j.core.impl;
+ exports org.apache.logging.log4j.core.jmx;
+ exports org.apache.logging.log4j.core.layout;
+ exports org.apache.logging.log4j.core.lookup;
+ exports org.apache.logging.log4j.core.message;
+ exports org.apache.logging.log4j.core.net;
+ exports org.apache.logging.log4j.core.net.ssl;
+ exports org.apache.logging.log4j.core.osgi;
+ exports org.apache.logging.log4j.core.parser;
+ exports org.apache.logging.log4j.core.pattern;
+ exports org.apache.logging.log4j.core.script;
+ exports org.apache.logging.log4j.core.selector;
+ exports org.apache.logging.log4j.core.time;
+ exports org.apache.logging.log4j.core.tools;
+ exports org.apache.logging.log4j.core.tools.picocli;
+ exports org.apache.logging.log4j.core.util;
+ exports org.apache.logging.log4j.core.util.datetime;
+
+ requires transitive java.desktop;
+ requires transitive java.management;
+ requires transitive java.naming;
+ requires transitive java.sql;
+ requires transitive java.rmi;
+ requires transitive java.scripting;
+ requires transitive java.xml;
+ requires transitive org.apache.logging.log4j;
+ requires transitive org.apache.logging.log4j.plugins;
+ requires transitive com.lmax.disruptor;
+ requires transitive org.jctools.core;
+ requires transitive org.osgi.framework;
+ requires transitive com.conversantmedia.disruptor;
+ requires transitive com.fasterxml.jackson.core;
+ requires transitive com.fasterxml.jackson.databind;
+ requires transitive com.fasterxml.jackson.dataformat.xml;
+ requires transitive com.fasterxml.jackson.dataformat.yaml;
+ requires transitive org.apache.commons.compress;
+ requires transitive org.fusesource.jansi;
+ uses org.apache.logging.log4j.core.util.ContextDataProvider;
+ uses org.apache.logging.log4j.core.util.WatchEventService;
+ provides org.apache.logging.log4j.message.ThreadDumpMessage.ThreadInfoFactory with org.apache.logging.log4j.core.message.ExtendedThreadInfoFactory;
+ provides org.apache.logging.log4j.core.util.ContextDataProvider with org.apache.logging.log4j.core.impl.ThreadContextDataProvider;
+ provides org.apache.logging.log4j.spi.Provider with org.apache.logging.log4j.core.impl.Log4jProvider;
+ provides org.apache.logging.log4j.plugins.processor.PluginService with org.apache.logging.log4j.core.plugins.Log4jPlugins;
+}
diff --cc log4j-plugin-processor/src/main/java/org/apache/logging/log4j/plugin/processor/BeanProcessor.java
index 0000000,0000000..3ab23ca
new file mode 100644
--- /dev/null
+++ b/log4j-plugin-processor/src/main/java/org/apache/logging/log4j/plugin/processor/BeanProcessor.java
@@@ -1,0 -1,0 +1,516 @@@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements. See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache license, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the license for the specific language governing permissions and
++ * limitations under the license.
++ */
++
++package org.apache.logging.log4j.plugin.processor;
++
++import org.apache.logging.log4j.plugins.di.DependentScoped;
++import org.apache.logging.log4j.plugins.di.Disposes;
++import org.apache.logging.log4j.plugins.di.Inject;
++import org.apache.logging.log4j.plugins.di.Producer;
++import org.apache.logging.log4j.plugins.di.Qualifier;
++import org.apache.logging.log4j.plugins.di.ScopeType;
++
++import javax.annotation.processing.AbstractProcessor;
++import javax.annotation.processing.RoundEnvironment;
++import javax.annotation.processing.SupportedAnnotationTypes;
++import javax.annotation.processing.SupportedOptions;
++import javax.lang.model.SourceVersion;
++import javax.lang.model.element.AnnotationMirror;
++import javax.lang.model.element.Element;
++import javax.lang.model.element.ElementKind;
++import javax.lang.model.element.ExecutableElement;
++import javax.lang.model.element.Modifier;
++import javax.lang.model.element.Name;
++import javax.lang.model.element.PackageElement;
++import javax.lang.model.element.TypeElement;
++import javax.lang.model.element.VariableElement;
++import javax.lang.model.type.DeclaredType;
++import javax.lang.model.type.TypeMirror;
++import javax.lang.model.util.ElementKindVisitor9;
++import javax.lang.model.util.Elements;
++import javax.lang.model.util.SimpleTypeVisitor9;
++import javax.lang.model.util.Types;
++import javax.tools.StandardLocation;
++import java.io.IOException;
++import java.io.PrintWriter;
++import java.io.UncheckedIOException;
++import java.util.ArrayList;
++import java.util.Comparator;
++import java.util.HashSet;
++import java.util.LinkedHashSet;
++import java.util.List;
++import java.util.Set;
++import java.util.function.Predicate;
++import java.util.stream.Collectors;
++import java.util.stream.Stream;
++
++@SupportedAnnotationTypes({"org.apache.logging.log4j.plugins.*", "org.apache.logging.log4j.core.config.plugins.*"})
++@SupportedOptions({"pluginPackage", "pluginClassName"})
++public class BeanProcessor extends AbstractProcessor {
++ public static final String PLUGIN_MODULE_SERVICE_FILE = "META-INF/services/org.apache.logging.log4j.plugins.di.model.PluginModule";
++
++ public BeanProcessor() {
++ }
++
++ @Override
++ public SourceVersion getSupportedSourceVersion() {
++ return SourceVersion.latestSupported();
++ }
++
++ private static class ProducerAnnotationVisitor extends ElementKindVisitor9<Void, Void> {
++ private final List<ProducerMethodMirror> producerMethods = new ArrayList<>();
++ private final List<ProducerFieldMirror> producerFields = new ArrayList<>();
++
++ @Override
++ public Void visitVariableAsField(final VariableElement e, final Void unused) {
++ producerFields.add(new ProducerFieldMirror(e));
++ return null;
++ }
++
++ @Override
++ public Void visitExecutableAsMethod(final ExecutableElement e, final Void unused) {
++ producerMethods.add(new ProducerMethodMirror(e));
++ return null;
++ }
++ }
++
++ private static class DisposesAnnotationVisitor extends ElementKindVisitor9<Void, Void> {
++ private final List<DisposesMirror> disposesParameters = new ArrayList<>();
++
++ @Override
++ public Void visitVariableAsParameter(final VariableElement e, final Void unused) {
++ disposesParameters.add(new DisposesMirror(e));
++ return null;
++ }
++ }
++
++ private static class InjectAnnotationVisitor extends ElementKindVisitor9<Void, Void> {
++ private final List<InjectionTargetMirror> injectableClasses = new ArrayList<>();
++
++ @Override
++ public Void visitVariableAsField(final VariableElement e, final Void unused) {
++ injectableClasses.add(new InjectionTargetMirror(((TypeElement) e.getEnclosingElement())));
++ return null;
++ }
++
++ @Override
++ public Void visitExecutableAsConstructor(final ExecutableElement e, final Void unused) {
++ injectableClasses.add(new InjectionTargetMirror((TypeElement) e.getEnclosingElement()));
++ return null;
++ }
++
++ @Override
++ public Void visitExecutableAsMethod(final ExecutableElement e, final Void unused) {
++ injectableClasses.add(new InjectionTargetMirror((TypeElement) e.getEnclosingElement()));
++ return null;
++ }
++ }
++
++ private static class QualifiedAnnotationVisitor extends ElementKindVisitor9<Void, Void> {
++ private final Predicate<AnnotationMirror> isProducerAnnotation;
++ private final List<InjectionTargetMirror> injectableClasses = new ArrayList<>();
++
++ private QualifiedAnnotationVisitor(final Predicate<AnnotationMirror> isProducerAnnotation) {
++ this.isProducerAnnotation = isProducerAnnotation;
++ }
++
++ @Override
++ public Void visitVariableAsField(final VariableElement e, final Void unused) {
++ if (e.getAnnotationMirrors().stream().noneMatch(isProducerAnnotation)) {
++ injectableClasses.add(new InjectionTargetMirror((TypeElement) e.getEnclosingElement()));
++ }
++ return null;
++ }
++
++ @Override
++ public Void visitVariableAsParameter(final VariableElement e, final Void unused) {
++ final Element enclosingExecutable = e.getEnclosingElement();
++ final TypeElement typeElement = (TypeElement) enclosingExecutable.getEnclosingElement();
++ if (enclosingExecutable.getKind() == ElementKind.CONSTRUCTOR ||
++ enclosingExecutable.getAnnotationMirrors().stream().noneMatch(isProducerAnnotation)) {
++ injectableClasses.add(new InjectionTargetMirror(typeElement));
++ }
++ return null;
++ }
++ }
++
++ private static class PluginAnnotationVisitor extends ElementKindVisitor9<Void, Void> {
++ private final List<GenericPluginMirror> plugins = new ArrayList<>();
++
++ @Override
++ public Void visitTypeAsClass(final TypeElement e, final Void unused) {
++ plugins.add(new GenericPluginMirror(e));
++ return null;
++ }
++ }
++
++ private static class ScopeTypeVisitor extends ElementKindVisitor9<TypeElement, Types> {
++ protected ScopeTypeVisitor(final TypeElement defaultValue) {
++ super(defaultValue);
++ }
++
++ @Override
++ public TypeElement visitType(final TypeElement e, final Types types) {
++ for (final AnnotationMirror annotationMirror : e.getAnnotationMirrors()) {
++ final DeclaredType annotationType = annotationMirror.getAnnotationType();
++ if (annotationType.getAnnotation(ScopeType.class) != null) {
++ return (TypeElement) annotationType.asElement();
++ }
++ }
++ return super.visitType(e, types);
++ }
++
++ @Override
++ public TypeElement visitVariableAsField(final VariableElement e, final Types types) {
++ return Stream.concat(e.getAnnotationMirrors().stream(), e.asType().getAnnotationMirrors().stream())
++ .map(AnnotationMirror::getAnnotationType)
++ .filter(type -> type.getAnnotation(ScopeType.class) != null)
++ .findFirst()
++ .map(type -> (TypeElement) type.asElement())
++ .orElse(super.DEFAULT_VALUE);
++ }
++
++ @Override
++ public TypeElement visitExecutableAsMethod(final ExecutableElement e, final Types types) {
++ return Stream.concat(e.getAnnotationMirrors().stream(), e.getReturnType().getAnnotationMirrors().stream())
++ .map(AnnotationMirror::getAnnotationType)
++ .filter(type -> type.getAnnotation(ScopeType.class) != null)
++ .findFirst()
++ .map(type -> (TypeElement) type.asElement())
++ .orElse(super.DEFAULT_VALUE);
++ }
++ }
++
++ interface PluginSourceMirror<E extends Element> {
++ E getElement();
++
++ TypeElement getDeclaringElement();
++
++ TypeMirror getType();
++ }
++
++ static class ProducerMethodMirror implements PluginSourceMirror<ExecutableElement> {
++ private final ExecutableElement element;
++
++ ProducerMethodMirror(final ExecutableElement element) {
++ this.element = element;
++ }
++
++ @Override
++ public ExecutableElement getElement() {
++ return element;
++ }
++
++ @Override
++ public TypeElement getDeclaringElement() {
++ return (TypeElement) element.getEnclosingElement();
++ }
++
++ @Override
++ public TypeMirror getType() {
++ return element.getReturnType();
++ }
++ }
++
++ static class ProducerFieldMirror implements PluginSourceMirror<VariableElement> {
++ private final VariableElement element;
++
++ ProducerFieldMirror(final VariableElement element) {
++ this.element = element;
++ }
++
++ @Override
++ public VariableElement getElement() {
++ return element;
++ }
++
++ @Override
++ public TypeElement getDeclaringElement() {
++ return (TypeElement) element.getEnclosingElement();
++ }
++
++ @Override
++ public TypeMirror getType() {
++ return element.asType();
++ }
++ }
++
++ static class InjectionTargetMirror implements PluginSourceMirror<TypeElement> {
++ private final TypeElement element;
++
++ InjectionTargetMirror(final TypeElement element) {
++ this.element = element;
++ }
++
++ @Override
++ public TypeElement getElement() {
++ return element;
++ }
++
++ @Override
++ public TypeElement getDeclaringElement() {
++ return element;
++ }
++
++ @Override
++ public TypeMirror getType() {
++ return element.asType();
++ }
++ }
++
++ static class DisposesMirror implements PluginSourceMirror<VariableElement> {
++ private final VariableElement element;
++
++ DisposesMirror(final VariableElement element) {
++ this.element = element;
++ }
++
++ @Override
++ public VariableElement getElement() {
++ return element;
++ }
++
++ @Override
++ public TypeElement getDeclaringElement() {
++ return (TypeElement) element.getEnclosingElement().getEnclosingElement();
++ }
++
++ @Override
++ public TypeMirror getType() {
++ return element.asType();
++ }
++ }
++
++ static class GenericPluginMirror implements PluginSourceMirror<TypeElement> {
++ private final TypeElement element;
++
++ GenericPluginMirror(final TypeElement element) {
++ this.element = element;
++ }
++
++ @Override
++ public TypeElement getElement() {
++ return element;
++ }
++
++ @Override
++ public TypeElement getDeclaringElement() {
++ return element;
++ }
++
++ @Override
++ public TypeMirror getType() {
++ return element.asType();
++ }
++ }
++
++ @Override
++ public boolean process(final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv) {
++ if (annotations.isEmpty()) {
++ return false;
++ }
++
++ final TypeElement[] producerAnnotations = annotations.stream()
++ .filter(e -> e.getAnnotation(Producer.class) != null)
++ .toArray(TypeElement[]::new);
++ final var producesAnnotationVisitor = new ProducerAnnotationVisitor();
++ roundEnv.getElementsAnnotatedWithAny(producerAnnotations).forEach(producesAnnotationVisitor::visit);
++
++ final var disposesAnnotationVisitor = new DisposesAnnotationVisitor();
++ roundEnv.getElementsAnnotatedWith(Disposes.class).forEach(disposesAnnotationVisitor::visit);
++
++ final var injectAnnotationVisitor = new InjectAnnotationVisitor();
++ roundEnv.getElementsAnnotatedWith(Inject.class).forEach(injectAnnotationVisitor::visit);
++
++ final Types types = processingEnv.getTypeUtils();
++ final var qualifiedAnnotationVisitor = new QualifiedAnnotationVisitor(annotationMirror -> {
++ for (final TypeElement producerAnnotation : producerAnnotations) {
++ if (types.isSameType(producerAnnotation.asType(), annotationMirror.getAnnotationType())) {
++ return true;
++ }
++ }
++ return false;
++ });
++ final TypeElement[] qualifierAnnotations = annotations.stream()
++ .filter(e -> e.getAnnotation(Qualifier.class) != null)
++ .toArray(TypeElement[]::new);
++ roundEnv.getElementsAnnotatedWithAny(qualifierAnnotations).forEach(qualifiedAnnotationVisitor::visit);
++
++ final TypeElement[] pluginAnnotations = annotations.stream()
++ .filter(e -> e.getSimpleName().contentEquals("Plugin"))
++ .toArray(TypeElement[]::new);
++ final var pluginAnnotationVisitor = new PluginAnnotationVisitor();
++ roundEnv.getElementsAnnotatedWithAny(pluginAnnotations).forEach(pluginAnnotationVisitor::visit);
++
++ final Set<PackageElement> packageElements = new HashSet<>();
++ final Set<TypeElement> declaringTypes = new HashSet<>();
++
++ final Elements elements = processingEnv.getElementUtils();
++ final List<PluginSourceMirror<?>> mirrors = new ArrayList<>(producesAnnotationVisitor.producerMethods);
++ mirrors.addAll(producesAnnotationVisitor.producerFields);
++ mirrors.addAll(injectAnnotationVisitor.injectableClasses);
++ mirrors.addAll(disposesAnnotationVisitor.disposesParameters);
++ mirrors.forEach(mirror -> {
++ declaringTypes.add(mirror.getDeclaringElement());
++ packageElements.add(elements.getPackageOf(mirror.getDeclaringElement()));
++ });
++
++ qualifiedAnnotationVisitor.injectableClasses.stream()
++ .filter(mirror -> !declaringTypes.contains(mirror.getDeclaringElement()))
++ .forEach(mirror -> {
++ mirrors.add(mirror);
++ declaringTypes.add(mirror.getDeclaringElement());
++ packageElements.add(elements.getPackageOf(mirror.getDeclaringElement()));
++ });
++
++ pluginAnnotationVisitor.plugins.stream()
++ .filter(mirror -> !declaringTypes.contains(mirror.getDeclaringElement()))
++ .forEach(mirror -> {
++ mirrors.add(mirror);
++ declaringTypes.add(mirror.getDeclaringElement());
++ packageElements.add(elements.getPackageOf(mirror.getDeclaringElement()));
++ });
++
++ String packageName = processingEnv.getOptions().get("pluginPackage");
++ if (packageName == null) {
++ packageName = packageElements.stream()
++ .map(PackageElement::getQualifiedName)
++ .map(CharSequence.class::cast)
++ .reduce(BeanProcessor::commonPrefix)
++ .orElseThrow()
++ .toString();
++ }
++ String className = processingEnv.getOptions().getOrDefault("pluginClassName", "Log4jModule");
++ try {
++ writePluginModule(packageName, className, mirrors);
++ return false;
++ } catch (IOException e) {
++ throw new UncheckedIOException(e);
++ }
++ }
++
++ private void writePluginModule(final CharSequence packageName, final CharSequence className,
++ final List<PluginSourceMirror<?>> mirrors) throws IOException {
++ try (final PrintWriter out = new PrintWriter(processingEnv.getFiler().createResource(
++ StandardLocation.CLASS_OUTPUT, "", PLUGIN_MODULE_SERVICE_FILE).openWriter())) {
++ out.println(packageName + ".plugins." + className);
++ }
++ try (final PrintWriter out = new PrintWriter(processingEnv.getFiler().createSourceFile(
++ packageName + ".plugins." + className).openWriter())) {
++ out.println("package " + packageName + ".plugins;");
++ out.println();
++ out.println("import org.apache.logging.log4j.plugins.di.model.*;");
++ out.println();
++ out.println("import java.util.List;");
++ out.println("import java.util.Set;");
++ out.println();
++ out.println("public class " + className + " extends PluginModule {");
++ out.println();
++ out.println(" private static final List<PluginSource> PLUGINS = List.of(" + javaListOfPlugins(mirrors) + ");");
++ out.println();
++ out.println(" public " + className + "() {");
++ out.println(" super(PLUGINS);");
++ out.println(" }");
++ out.println();
++ out.println("}");
++ }
++ }
++
++ private String javaListOfPlugins(final List<PluginSourceMirror<?>> mirrors) {
++ final Elements elements = processingEnv.getElementUtils();
++ final Types types = processingEnv.getTypeUtils();
++ final var scopeTypeVisitor = new ScopeTypeVisitor(elements.getTypeElement(DependentScoped.class.getCanonicalName()));
++ return mirrors.stream()
++ .sorted(Comparator.<PluginSourceMirror<?>, String>comparing(m -> m.getClass().getName())
++ .thenComparing(m -> elements.getBinaryName(m.getDeclaringElement()), CharSequence::compare))
++ .map(mirror -> {
++ final String declaringClassName = '"' + elements.getBinaryName(mirror.getDeclaringElement()).toString() + '"';
++ final String setOfImplementedInterfaces = javaSetOfImplementedInterfaces(mirror.getType());
++ final String scopeTypeClassReference = mirror.getElement().accept(scopeTypeVisitor, types).getQualifiedName() + ".class";
++ if (mirror instanceof ProducerMethodMirror) {
++ return "new ProducerMethod(" + declaringClassName + ", \"" +
++ mirror.getType().toString() + "\", \"" +
++ mirror.getElement().getSimpleName() + "\", " +
++ setOfImplementedInterfaces + ", " +
++ scopeTypeClassReference + ")";
++ } else if (mirror instanceof ProducerFieldMirror) {
++ return "new ProducerField(" + declaringClassName + ", \"" +
++ mirror.getElement().getSimpleName() + "\", " +
++ setOfImplementedInterfaces + ", " +
++ scopeTypeClassReference + ")";
++ } else if (mirror instanceof InjectionTargetMirror) {
++ return "new InjectionTarget(" + declaringClassName + ", " +
++ setOfImplementedInterfaces + ", " +
++ scopeTypeClassReference + ")";
++ } else if (mirror instanceof DisposesMirror) {
++ return "new DisposesMethod(" + declaringClassName + ", \"" +
++ elements.getBinaryName((TypeElement) types.asElement(mirror.getElement().asType())) + "\")";
++ } else if (mirror instanceof GenericPluginMirror) {
++ return "new GenericPlugin(" + declaringClassName + ", " + setOfImplementedInterfaces + ")";
++ } else {
++ throw new UnsupportedOperationException(mirror.getClass().getName());
++ }
++ })
++ .collect(Collectors.joining(",\n", "\n", "\n"));
++ }
++
++ private String javaSetOfImplementedInterfaces(final TypeMirror base) {
++ final Set<Name> implementedInterfaces = getImplementedInterfaces(base);
++ return implementedInterfaces.isEmpty() ? "Set.of()" : "Set.of(" +
++ implementedInterfaces.stream().map(name -> name + ".class").collect(Collectors.joining(", ")) +
++ ")";
++ }
++
++ private Set<Name> getImplementedInterfaces(final TypeMirror base) {
++ final Set<Name> implementedInterfaces = new LinkedHashSet<>();
++ final Types types = processingEnv.getTypeUtils();
++ base.accept(new SimpleTypeVisitor9<Void, Void>() {
++ @Override
++ public Void visitDeclared(final DeclaredType t, final Void unused) {
++ for (final TypeMirror directSupertype : types.directSupertypes(t)) {
++ directSupertype.accept(this, null);
++ }
++ t.asElement().accept(new ElementKindVisitor9<Void, Void>() {
++ @Override
++ public Void visitTypeAsInterface(final TypeElement e, final Void unused) {
++ if (e.getModifiers().contains(Modifier.PUBLIC)) {
++ implementedInterfaces.add(e.getQualifiedName());
++ }
++ return null;
++ }
++ }, null);
++ return null;
++ }
++ }, null);
++ return implementedInterfaces;
++ }
++
++ private static CharSequence commonPrefix(final CharSequence str1, final CharSequence str2) {
++ final int minLength = Math.min(str1.length(), str2.length());
++ for (int i = 0; i < minLength; i++) {
++ if (str1.charAt(i) != str2.charAt(i)) {
++ if (i > 1 && str1.charAt(i - 1) == '.') {
++ return str1.subSequence(0, i - 1);
++ } else {
++ return str1.subSequence(0, i);
++ }
++ }
++ }
++ return str1.subSequence(0, minLength);
++ }
++
++}
diff --cc log4j-plugin-processor/src/main/java/org/apache/logging/log4j/plugin/processor/PluginProcessor.java
index df16f58,0000000..bd3d693
mode 100644,000000..100644
--- a/log4j-plugin-processor/src/main/java/org/apache/logging/log4j/plugin/processor/PluginProcessor.java
+++ b/log4j-plugin-processor/src/main/java/org/apache/logging/log4j/plugin/processor/PluginProcessor.java
@@@ -1,276 -1,0 +1,273 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.plugin.processor;
+
+import org.apache.logging.log4j.LoggingException;
+import org.apache.logging.log4j.plugins.Plugin;
+import org.apache.logging.log4j.plugins.PluginAliases;
+import org.apache.logging.log4j.plugins.processor.PluginEntry;
- import org.apache.logging.log4j.plugins.util.PluginManager;
+import org.apache.logging.log4j.util.Strings;
+
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.Messager;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementVisitor;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.Elements;
- import javax.lang.model.util.SimpleElementVisitor7;
++import javax.lang.model.util.SimpleElementVisitor8;
+import javax.tools.Diagnostic.Kind;
+import javax.tools.FileObject;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardLocation;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+/**
+ * Annotation processor for pre-scanning Log4j 2 plugins.
+ */
+@SupportedAnnotationTypes({"org.apache.logging.log4j.plugins.*", "org.apache.logging.log4j.core.config.plugins.*"})
+public class PluginProcessor extends AbstractProcessor {
+
+ // TODO: this could be made more abstract to allow for compile-time and run-time plugin processing
+
+ private static final String SERVICE_FILE_NAME =
+ "META-INF/services/org.apache.logging.log4j.plugins.processor.PluginService";
+
+ public PluginProcessor() {
+ }
+
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.latest();
+ }
+
+ @Override
+ public boolean process(final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv) {
+ Map<String, String> options = processingEnv.getOptions();
+ String packageName = options.get("pluginPackage");
+ Messager messager = processingEnv.getMessager();
+ messager.printMessage(Kind.NOTE, "Processing Log4j annotations");
+ try {
+ final Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(Plugin.class);
+ if (elements.isEmpty()) {
+ messager.printMessage(Kind.NOTE, "No elements to process");
+ return false;
+ }
+ messager.printMessage(Kind.NOTE, "Retrieved " + elements.size() + " Plugin elements");
+ List<PluginEntry> list = new ArrayList<>();
+ packageName = collectPlugins(packageName, elements, list);
+ writeClassFile(packageName, list);
+ writeServiceFile(packageName);
+ messager.printMessage(Kind.NOTE, "Annotations processed");
- return true;
+ } catch (final Exception ex) {
- ex.printStackTrace();
+ error(ex.getMessage());
- return false;
+ }
++ return false;
+ }
+
+ private void error(final CharSequence message) {
+ processingEnv.getMessager().printMessage(Kind.ERROR, message);
+ }
+
+ private String collectPlugins(String packageName, final Iterable<? extends Element> elements, List<PluginEntry> list) {
+ boolean calculatePackage = packageName == null;
+ final Elements elementUtils = processingEnv.getElementUtils();
+ final ElementVisitor<PluginEntry, Plugin> pluginVisitor = new PluginElementVisitor(elementUtils);
+ final ElementVisitor<Collection<PluginEntry>, Plugin> pluginAliasesVisitor = new PluginAliasesElementVisitor(
+ elementUtils);
+ for (final Element element : elements) {
+ final Plugin plugin = element.getAnnotation(Plugin.class);
+ if (plugin == null) {
+ continue;
+ }
+ final PluginEntry entry = element.accept(pluginVisitor, plugin);
+ list.add(entry);
+ if (calculatePackage) {
+ packageName = calculatePackage(elementUtils, element, packageName);
+ }
+ final Collection<PluginEntry> entries = element.accept(pluginAliasesVisitor, plugin);
+ for (final PluginEntry pluginEntry : entries) {
+ list.add(pluginEntry);
+ }
+ }
+ return packageName;
+ }
+
+ private String calculatePackage(Elements elements, Element element, String packageName) {
+ Name name = elements.getPackageOf(element).getQualifiedName();
+ if (name == null) {
+ return null;
+ }
+ String pkgName = name.toString();
+ if (packageName == null) {
+ return pkgName;
+ }
+ if (pkgName.length() == packageName.length()) {
+ return packageName;
+ }
+ if (pkgName.length() < packageName.length() && packageName.startsWith(pkgName)) {
+ return pkgName;
+ }
+
+ return commonPrefix(pkgName, packageName);
+ }
+
+ private void writeServiceFile(String pkgName) throws IOException {
+ final FileObject fileObject = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, Strings.EMPTY,
+ SERVICE_FILE_NAME);
+ try (final PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(fileObject.openOutputStream(), UTF_8)))) {
+ writer.println(createFqcn(pkgName));
+ }
+ }
+
+ private void writeClassFile(String pkg, List<PluginEntry> list) {
+ String fqcn = createFqcn(pkg);
+ try (final PrintWriter writer = createSourceFile(fqcn)) {
+ writer.println("package " + pkg + ".plugins;");
+ writer.println("");
+ writer.println("import org.apache.logging.log4j.plugins.processor.PluginEntry;");
+ writer.println("import org.apache.logging.log4j.plugins.processor.PluginService;");
+ writer.println("");
+ writer.println("public class Log4jPlugins extends PluginService {");
+ writer.println("");
+ writer.println(" private static PluginEntry[] entries = new PluginEntry[] {");
+ StringBuilder sb = new StringBuilder();
+ int max = list.size() - 1;
+ for (int i = 0; i < list.size(); ++i) {
+ PluginEntry entry = list.get(i);
+ sb.append(" ").append("new PluginEntry(\"");
+ sb.append(entry.getKey()).append("\", \"");
+ sb.append(entry.getClassName()).append("\", \"");
+ sb.append(entry.getName()).append("\", ");
+ sb.append(entry.isPrintable()).append(", ");
+ sb.append(entry.isDefer()).append(", \"");
+ sb.append(entry.getCategory()).append("\")");
+ if (i < max) {
+ sb.append(",");
+ }
+ writer.println(sb.toString());
+ sb.setLength(0);
+ }
+ writer.println(" };");
+ writer.println(" @Override");
+ writer.println(" public PluginEntry[] getEntries() { return entries;}");
+ writer.println("}");
+ }
+ }
+
+ private PrintWriter createSourceFile(String fqcn) {
+ try {
+ JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(fqcn);
+ return new PrintWriter(sourceFile.openWriter());
+ } catch (IOException e) {
+ throw new LoggingException("Unable to create Plugin Service Class " + fqcn, e);
+ }
+ }
+
+ private String createFqcn(String packageName) {
+ return packageName + ".plugins.Log4jPlugins";
+ }
+
+ /**
+ * ElementVisitor to scan the Plugin annotation.
+ */
- private static class PluginElementVisitor extends SimpleElementVisitor7<PluginEntry, Plugin> {
++ private static class PluginElementVisitor extends SimpleElementVisitor8<PluginEntry, Plugin> {
+
+ private final Elements elements;
+
+ private PluginElementVisitor(final Elements elements) {
+ this.elements = elements;
+ }
+
+ @Override
+ public PluginEntry visitType(final TypeElement e, final Plugin plugin) {
+ Objects.requireNonNull(plugin, "Plugin annotation is null.");
+ final PluginEntry entry = new PluginEntry();
+ entry.setKey(plugin.name().toLowerCase(Locale.US));
+ entry.setClassName(elements.getBinaryName(e).toString());
+ entry.setName(Plugin.EMPTY.equals(plugin.elementType()) ? plugin.name() : plugin.elementType());
+ entry.setPrintable(plugin.printObject());
+ entry.setDefer(plugin.deferChildren());
+ entry.setCategory(plugin.category());
+ return entry;
+ }
+ }
+
+ private String commonPrefix(String str1, String str2) {
- int minLength = str1.length() < str2.length() ? str1.length() : str2.length();
++ int minLength = Math.min(str1.length(), str2.length());
+ for (int i = 0; i < minLength; i++) {
+ if (str1.charAt(i) != str2.charAt(i)) {
+ if (i > 1 && str1.charAt(i-1) == '.') {
+ return str1.substring(0, i-1);
+ } else {
+ return str1.substring(0, i);
+ }
+ }
+ }
+ return str1.substring(0, minLength);
+ }
+
+ /**
+ * ElementVisitor to scan the PluginAliases annotation.
+ */
- private static class PluginAliasesElementVisitor extends SimpleElementVisitor7<Collection<PluginEntry>, Plugin> {
++ private static class PluginAliasesElementVisitor extends SimpleElementVisitor8<Collection<PluginEntry>, Plugin> {
+
+ private final Elements elements;
+
+ private PluginAliasesElementVisitor(final Elements elements) {
- super(Collections.<PluginEntry> emptyList());
++ super(Collections.emptyList());
+ this.elements = elements;
+ }
+
+ @Override
+ public Collection<PluginEntry> visitType(final TypeElement e, final Plugin plugin) {
+ final PluginAliases aliases = e.getAnnotation(PluginAliases.class);
+ if (aliases == null) {
+ return DEFAULT_VALUE;
+ }
+ final Collection<PluginEntry> entries = new ArrayList<>(aliases.value().length);
+ for (final String alias : aliases.value()) {
+ final PluginEntry entry = new PluginEntry();
+ entry.setKey(alias.toLowerCase(Locale.US));
+ entry.setClassName(elements.getBinaryName(e).toString());
+ entry.setName(Plugin.EMPTY.equals(plugin.elementType()) ? alias : plugin.elementType());
+ entry.setPrintable(plugin.printObject());
+ entry.setDefer(plugin.deferChildren());
+ entry.setCategory(plugin.category());
+ entries.add(entry);
+ }
+ return entries;
+ }
+ }
+}
diff --cc log4j-plugin-processor/src/main/java9/module-info.java
index dae6806,0000000..49dbeba
mode 100644,000000..100644
--- a/log4j-plugin-processor/src/main/java9/module-info.java
+++ b/log4j-plugin-processor/src/main/java9/module-info.java
@@@ -1,26 -1,0 +1,28 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+module org.apache.logging.log4j.plugin.processor {
+ exports org.apache.logging.log4j.plugin.processor;
+
+ requires java.compiler;
+ requires org.apache.logging.log4j;
+ requires org.apache.logging.log4j.plugins;
+ requires transitive org.osgi.framework;
+
- provides javax.annotation.processing.Processor with org.apache.logging.log4j.plugin.processor.PluginProcessor;
++ provides javax.annotation.processing.Processor with
++ org.apache.logging.log4j.plugin.processor.PluginProcessor,
++ org.apache.logging.log4j.plugin.processor.BeanProcessor;
+}
diff --cc log4j-plugin-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor
index e1c421c,0000000..1c97759
mode 100644,000000..100644
--- a/log4j-plugin-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor
+++ b/log4j-plugin-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor
@@@ -1,17 -1,0 +1,18 @@@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache license, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the license for the specific language governing permissions and
+# limitations under the license.
+#
+org.apache.logging.log4j.plugin.processor.PluginProcessor
++org.apache.logging.log4j.plugin.processor.BeanProcessor
diff --cc log4j-plugins-test/pom.xml
index c21c306,0000000..6c32550
mode 100644,000000..100644
--- a/log4j-plugins-test/pom.xml
+++ b/log4j-plugins-test/pom.xml
@@@ -1,312 -1,0 +1,320 @@@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache license, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the license for the specific language governing permissions and
+ ~ limitations under the license.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ <relativePath>../</relativePath>
+ </parent>
+ <artifactId>log4j-plugins-test</artifactId>
+ <packaging>jar</packaging>
+ <name>Apache Log4j Plugins Test</name>
+ <description>Log4j Plugin Test Support</description>
+ <properties>
+ <log4jParentDir>${basedir}/..</log4jParentDir>
+ <docLabel>Plugin Documentation</docLabel>
+ <projectDir>/plugins</projectDir>
+ <maven.doap.skip>true</maven.doap.skip>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-plugin-processor</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-plugins</artifactId>
+ </dependency>
+ <!-- Used for OSGi bundle support -->
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.framework</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.resource</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <!-- TEST DEPENDENCIES -->
+
+ <!-- Pull in useful test classes from API -->
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-api-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.vintage</groupId>
+ <artifactId>junit-vintage-engine</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-engine</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>${compiler.plugin.version}</version>
+ <configuration>
+ <source>${maven.compiler.source}</source>
+ <target>${maven.compiler.target}</target>
+ <release>${maven.compiler.release}</release>
+ <showDeprecation>true</showDeprecation>
+ <showWarnings>true</showWarnings>
+ <verbose>false</verbose>
+ <encoding>UTF-8</encoding>
+ <fork>true</fork>
+ <meminitial>256</meminitial>
+ <maxmem>1024</maxmem>
+ <compilerArgs>
+ <arg>-XDcompilePolicy=simple</arg>
+ <arg>-Xplugin:ErrorProne</arg>
+ <!--
+ https://errorprone.info/docs/installation
+ in Java 16+, https://openjdk.java.net/jeps/396 encapsulates internals that errorprone needs
+ -->
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED</arg>
+ <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED</arg>
+ <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED</arg>
+ </compilerArgs>
+ <compilerArguments>
+ <Xmaxwarns>10000</Xmaxwarns>
+ <Xlint />
+ </compilerArguments>
+ <annotationProcessorPaths>
+ <path>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-plugin-processor</artifactId>
+ <version>${project.version}</version>
+ </path>
+ <path>
+ <groupId>com.google.errorprone</groupId>
+ <artifactId>error_prone_core</artifactId>
+ <version>${errorprone.version}</version>
+ </path>
+ </annotationProcessorPaths>
+ <forceJavacCompilerUse>true</forceJavacCompilerUse>
+ <parameters>true</parameters>
+ </configuration>
+ <executions>
+ <execution>
+ <id>compile-module-info</id>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ <phase>prepare-package</phase>
+ <configuration>
+ <compileSourceRoots>
+ <compileSourceRoot>${project.basedir}/src/main/java9</compileSourceRoot>
+ </compileSourceRoots>
+ </configuration>
+ </execution>
++ <execution>
++ <id>default-testCompile</id>
++ <configuration>
++ <compilerArgs>
++ <arg>-ApluginPackage=org.apache.logging.log4j.plugins.convert.test</arg>
++ </compilerArgs>
++ </configuration>
++ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <useModulePath>false</useModulePath>
+ <excludedGroups>
+ org.apache.logging.log4j.categories.PerformanceTests
+ </excludedGroups>
+ <systemPropertyVariables>
+ <org.apache.activemq.SERIALIZABLE_PACKAGES>*</org.apache.activemq.SERIALIZABLE_PACKAGES>
+ </systemPropertyVariables>
+ <argLine>--add-opens java.base/java.net=ALL-UNNAMED</argLine>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <configuration>
+ <skipTests>true</skipTests>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>org.apache.logging.log4j.plugins</Bundle-SymbolicName>
+ <!-- TODO: exclude internal classes from export -->
+ <Export-Package>org.apache.logging.log4j.plugins.*</Export-Package>
+ <Import-Package>
+ org.apache.logging.log4j,
+ org.apache.logging.log4j.status,
+ org.apache.logging.log4j.util,
+ org.osgi.framework.*
+ </Import-Package>
+ <Bundle-Activator>org.apache.logging.log4j.plugins.osgi.Activator</Bundle-Activator>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-changes-plugin</artifactId>
+ <version>${changes.plugin.version}</version>
+ <reportSets>
+ <reportSet>
+ <reports>
+ <report>changes-report</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ <configuration>
+ <issueLinkTemplate>%URL%/%ISSUE%</issueLinkTemplate>
+ <useJql>true</useJql>
+ <component>Plugins</component>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <version>${checkstyle.plugin.version}</version>
+ <configuration>
+ <!--<propertiesLocation>${vfs.parent.dir}/checkstyle.properties</propertiesLocation> -->
+ <configLocation>${log4jParentDir}/checkstyle.xml</configLocation>
+ <suppressionsLocation>${log4jParentDir}/checkstyle-suppressions.xml</suppressionsLocation>
+ <enableRulesSummary>false</enableRulesSummary>
+ <propertyExpansion>basedir=${basedir}</propertyExpansion>
+ <propertyExpansion>licensedir=${log4jParentDir}/checkstyle-header.txt</propertyExpansion>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>${javadoc.plugin.version}</version>
+ <configuration>
+ <failOnError>false</failOnError>
+ <source>8</source>
+ <bottom><![CDATA[<p align="center">Copyright © {inceptionYear}-{currentYear} {organizationName}. All Rights Reserved.<br />
+ Apache Logging, Apache Log4j, Log4j, Apache, the Apache feather logo, the Apache Logging project logo,
+ and the Apache Log4j logo are trademarks of The Apache Software Foundation.</p>]]></bottom>
+ <!-- module link generation is completely broken in the javadoc plugin for a multi-module non-aggregating
+ project -->
+ <additionalparam>${javadoc.opts}</additionalparam>
+ <detectOfflineLinks>false</detectOfflineLinks>
+ <linksource>true</linksource>
+ <links>
+ <link>http://docs.oracle.com/javaee/6/api/</link>
+ <link>http://www.osgi.org/javadoc/r4v43/core/</link>
+ <link>https://commons.apache.org/proper/commons-lang/javadocs/api-release/</link>
+ </links>
+ <groups>
+ <group>
+ <title>Core API</title>
+ <packages>org.apache.logging.log4j.core</packages>
+ </group>
+ <group>
+ <title>Configuration</title>
+ <packages>org.apache.logging.log4j.core.config*:org.apache.logging.log4j.core.selector</packages>
+ </group>
+ <group>
+ <title>Core Plugins</title>
+ <packages>org.apache.logging.log4j.core.appender*:org.apache.logging.log4j.core.filter:org.apache.logging.log4j.core.layout:org.apache.logging.log4j.core.lookup:org.apache.logging.log4j.core.pattern:org.apache.logging.log4j.core.script</packages>
+ </group>
+ <group>
+ <title>Tools</title>
+ <packages>org.apache.logging.log4j.core.net*:org.apache.logging.log4j.core.tools</packages>
+ </group>
+ <group>
+ <title>Internals</title>
+ <packages>org.apache.logging.log4j.core.async:org.apache.logging.log4j.core.impl:org.apache.logging.log4j.core.util*:org.apache.logging.log4j.core.osgi:org.apache.logging.log4j.core.jackson:org.apache.logging.log4j.core.jmx</packages>
+ </group>
+ </groups>
+ </configuration>
+ <reportSets>
+ <reportSet>
+ <id>non-aggregate</id>
+ <reports>
+ <report>javadoc</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ <plugin>
+ <groupId>com.github.spotbugs</groupId>
+ <artifactId>spotbugs-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jxr-plugin</artifactId>
+ <version>${jxr.plugin.version}</version>
+ <reportSets>
+ <reportSet>
+ <id>non-aggregate</id>
+ <reports>
+ <report>jxr</report>
+ </reports>
+ </reportSet>
+ <reportSet>
+ <id>aggregate</id>
+ <reports>
+ <report>aggregate</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pmd-plugin</artifactId>
+ <version>${pmd.plugin.version}</version>
+ <configuration>
+ <targetJdk>${maven.compiler.target}</targetJdk>
+ </configuration>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
+
diff --cc log4j-plugins-test/src/main/java/org/apache/logging/log4j/plugins/test/validation/FakePlugin.java
index 48ea7dc,0000000..d257e51
mode 100644,000000..100644
--- a/log4j-plugins-test/src/main/java/org/apache/logging/log4j/plugins/test/validation/FakePlugin.java
+++ b/log4j-plugins-test/src/main/java/org/apache/logging/log4j/plugins/test/validation/FakePlugin.java
@@@ -1,33 -1,0 +1,33 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
- package org.apache.logging.log4j.plugins.processor;
++package org.apache.logging.log4j.plugins.test.validation;
+
+import org.apache.logging.log4j.plugins.Plugin;
+import org.apache.logging.log4j.plugins.PluginAliases;
+
+/**
+ * Test plugin class for unit tests.
+ */
+@Plugin(name = "Fake", category = "Test")
+@PluginAliases({"AnotherFake", "StillFake"})
+public class FakePlugin {
+
+ @Plugin(name = "Nested", category = "Test")
+ public static class Nested {
+ }
+}
diff --cc log4j-plugins-test/src/main/java/org/apache/logging/log4j/plugins/test/validation/ProductionBean.java
index 0000000,51cd722..51cd722
mode 000000,100644..100644
--- a/log4j-plugins-test/src/main/java/org/apache/logging/log4j/plugins/test/validation/ProductionBean.java
+++ b/log4j-plugins-test/src/main/java/org/apache/logging/log4j/plugins/test/validation/ProductionBean.java
diff --cc log4j-plugins-test/src/main/java9/module-info.java
index 6884125,0000000..885afe6
mode 100644,000000..100644
--- a/log4j-plugins-test/src/main/java9/module-info.java
+++ b/log4j-plugins-test/src/main/java9/module-info.java
@@@ -1,24 -1,0 +1,25 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+module org.apache.logging.log4j.plugins.test {
+ exports org.apache.logging.log4j.plugins.test.validation;
+
+ requires org.apache.logging.log4j;
+ requires org.apache.logging.log4j.plugins;
+
+ provides org.apache.logging.log4j.plugins.processor.PluginService with org.apache.logging.log4j.plugins.test.validation.plugins.Log4jPlugins;
++ provides org.apache.logging.log4j.plugins.di.model.PluginModule with org.apache.logging.log4j.plugins.test.validation.plugins.Log4jModule;
+}
diff --cc log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugin/processor/BeanProcessorTest.java
index 0000000,0000000..624c803
new file mode 100644
--- /dev/null
+++ b/log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugin/processor/BeanProcessorTest.java
@@@ -1,0 -1,0 +1,51 @@@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements. See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache license, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the license for the specific language governing permissions and
++ * limitations under the license.
++ */
++
++package org.apache.logging.log4j.plugin.processor;
++
++import org.apache.logging.log4j.plugins.di.model.DisposesMethod;
++import org.apache.logging.log4j.plugins.di.model.GenericPlugin;
++import org.apache.logging.log4j.plugins.di.model.InjectionTarget;
++import org.apache.logging.log4j.plugins.di.model.PluginModule;
++import org.apache.logging.log4j.plugins.di.model.ProducerField;
++import org.apache.logging.log4j.plugins.test.validation.FakePlugin;
++import org.apache.logging.log4j.plugins.test.validation.plugins.Log4jModule;
++import org.junit.jupiter.api.Test;
++
++import static org.junit.jupiter.api.Assertions.assertTrue;
++
++class BeanProcessorTest {
++ @Test
++ void smokeTests() {
++ final PluginModule module = new Log4jModule();
++ final var plugins = module.getPluginSources();
++ assertTrue(plugins.stream().anyMatch(plugin -> plugin instanceof InjectionTarget &&
++ plugin.getDeclaringClassName().equals("org.apache.logging.log4j.plugins.test.validation.ExampleBean")));
++ assertTrue(plugins.stream().anyMatch(plugin -> plugin instanceof InjectionTarget &&
++ plugin.getDeclaringClassName().equals("org.apache.logging.log4j.plugins.test.validation.ImplicitBean")));
++ assertTrue(plugins.stream().anyMatch(plugin -> plugin instanceof InjectionTarget &&
++ plugin.getDeclaringClassName().equals("org.apache.logging.log4j.plugins.test.validation.ImplicitMethodBean")));
++ assertTrue(plugins.stream().anyMatch(plugin -> plugin instanceof InjectionTarget &&
++ plugin.getDeclaringClassName().equals("org.apache.logging.log4j.plugins.test.validation.ProductionBean$Builder")));
++ assertTrue(plugins.stream().anyMatch(plugin -> plugin instanceof ProducerField &&
++ plugin.getDeclaringClassName().equals("org.apache.logging.log4j.plugins.test.validation.ProductionBean")));
++ assertTrue(plugins.stream().anyMatch(plugin -> plugin instanceof DisposesMethod &&
++ plugin.getDeclaringClassName().equals("org.apache.logging.log4j.plugins.test.validation.ProductionBean")));
++ assertTrue(plugins.stream().anyMatch(plugin -> plugin instanceof GenericPlugin &&
++ plugin.getDeclaringClassName().equals(FakePlugin.class.getName())));
++ }
++}
diff --cc log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugin/processor/PluginProcessorTest.java
index 7a0a7fe,0000000..8d8f02e
mode 100644,000000..100644
--- a/log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugin/processor/PluginProcessorTest.java
+++ b/log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugin/processor/PluginProcessorTest.java
@@@ -1,112 -1,0 +1,111 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.plugin.processor;
+
+import org.apache.logging.log4j.plugins.Plugin;
+import org.apache.logging.log4j.plugins.PluginAliases;
- import org.apache.logging.log4j.plugins.processor.FakePlugin;
+import org.apache.logging.log4j.plugins.processor.PluginEntry;
+import org.apache.logging.log4j.plugins.processor.PluginService;
++import org.apache.logging.log4j.plugins.test.validation.FakePlugin;
++import org.apache.logging.log4j.plugins.test.validation.plugins.Log4jPlugins;
+import org.apache.logging.log4j.plugins.util.PluginType;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+@RunWith(JUnit4.class)
+public class PluginProcessorTest {
+
+ private static PluginService pluginService;
+
+ private final Plugin p = FakePlugin.class.getAnnotation(Plugin.class);
+
+ @BeforeClass
- public static void setUpClass() throws Exception {
- Class<?> clazz = PluginProcessor.class.getClassLoader().loadClass("org.apache.logging.log4j.plugins.plugins.Log4jPlugins");
- assertNotNull("Could not locate plugins class", clazz);
- pluginService = (PluginService) clazz.getDeclaredConstructor().newInstance();;
++ public static void setUpClass() {
++ pluginService = new Log4jPlugins();
+ }
+
+ @Test
+ public void testTestCategoryFound() throws Exception {
+ assertNotNull("No plugin annotation on FakePlugin.", p);
+ final List<PluginType<?>> testCategory = pluginService.getCategory(p.category());
+ assertNotEquals("No plugins were found.", 0, pluginService.size());
+ assertNotNull("The category '" + p.category() + "' was not found.", testCategory);
+ assertFalse(testCategory.isEmpty());
+ }
+
+ @Test
+ public void testFakePluginFoundWithCorrectInformation() throws Exception {
+ final List<PluginType<?>> list = pluginService.getCategory(p.category());
+ assertNotNull(list);
+ final PluginEntry fake = getEntry(list, p.name());
+ assertNotNull(fake);
+ verifyFakePluginEntry(p.name(), fake);
+ }
+
+ @Test
+ public void testFakePluginAliasesContainSameInformation() throws Exception {
+ final PluginAliases aliases = FakePlugin.class.getAnnotation(PluginAliases.class);
+ for (final String alias : aliases.value()) {
+ final List<PluginType<?>> list = pluginService.getCategory(p.category());
+ assertNotNull(list);
+ final PluginEntry fake = getEntry(list, alias);
+ assertNotNull(fake);
+ verifyFakePluginEntry(alias, fake);
+ }
+ }
+
+ private void verifyFakePluginEntry(final String name, final PluginEntry fake) {
+ assertNotNull("The plugin '" + name.toLowerCase() + "' was not found.", fake);
+ assertEquals(FakePlugin.class.getName(), fake.getClassName());
+ assertEquals(name.toLowerCase(), fake.getKey());
+ assertEquals(Plugin.EMPTY, p.elementType());
+ assertEquals(name, fake.getName());
+ assertEquals(p.printObject(), fake.isPrintable());
+ assertEquals(p.deferChildren(), fake.isDefer());
+ }
+
+ @Test
+ public void testNestedPlugin() throws Exception {
+ final Plugin p = FakePlugin.Nested.class.getAnnotation(Plugin.class);
+ final List<PluginType<?>> list = pluginService.getCategory(p.category());
+ assertNotNull(list);
+ final PluginEntry nested = getEntry(list, p.name());
+ assertNotNull(nested);
+ assertEquals(p.name().toLowerCase(), nested.getKey());
+ assertEquals(FakePlugin.Nested.class.getName(), nested.getClassName());
+ assertEquals(p.name(), nested.getName());
+ assertEquals(Plugin.EMPTY, p.elementType());
+ assertEquals(p.printObject(), nested.isPrintable());
+ assertEquals(p.deferChildren(), nested.isDefer());
+ }
+
+ private PluginEntry getEntry(List<PluginType<?>> list, String name) {
+ for (PluginType<?> type : list) {
+ if (type.getPluginEntry().getName().equalsIgnoreCase(name)) {
+ return type.getPluginEntry();
+ }
+ }
+ return null;
+ }
+}
diff --cc log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/convert/TypeConverterRegistryTest.java
index 008c7bd,0000000..bb37ba8
mode 100644,000000..100644
--- a/log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/convert/TypeConverterRegistryTest.java
+++ b/log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/convert/TypeConverterRegistryTest.java
@@@ -1,160 -1,0 +1,162 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.plugins.convert;
+
+import org.apache.logging.log4j.plugins.Plugin;
- import org.junit.Test;
++import org.junit.jupiter.api.Test;
+
++import static org.hamcrest.MatcherAssert.*;
+import static org.hamcrest.Matchers.instanceOf;
- import static org.junit.Assert.*;
++import static org.junit.jupiter.api.Assertions.*;
+
+public class TypeConverterRegistryTest {
+
- @Test(expected = NullPointerException.class)
++ @Test
+ public void testFindNullConverter() {
- TypeConverterRegistry.getInstance().findCompatibleConverter(null);
++ assertThrows(NullPointerException.class,
++ () -> TypeConverterRegistry.getInstance().findCompatibleConverter(null));
+ }
+
+ @Test
+ public void testFindBooleanConverter() throws Exception {
+ final TypeConverter<?> converter = TypeConverterRegistry.getInstance().findCompatibleConverter(Boolean.class);
+ assertNotNull(converter);
+ assertTrue((Boolean) converter.convert("TRUE"));
+ }
+
+ @Test
+ public void testFindPrimitiveBooleanConverter() throws Exception {
+ final TypeConverter<?> converter = TypeConverterRegistry.getInstance().findCompatibleConverter(Boolean.TYPE);
+ assertNotNull(converter);
+ assertTrue((Boolean) converter.convert("tRUe"));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testFindCharSequenceConverterUsingStringConverter() throws Exception {
+ final TypeConverter<CharSequence> converter = (TypeConverter<CharSequence>)
+ TypeConverterRegistry.getInstance().findCompatibleConverter(CharSequence.class);
+ assertNotNull(converter);
+ assertThat(converter, instanceOf(TypeConverters.StringConverter.class));
+ final CharSequence expected = "This is a test sequence of characters";
+ final CharSequence actual = converter.convert(expected.toString());
+ assertEquals(expected, actual);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testFindNumberConverter() throws Exception {
+ final TypeConverter<Number> numberTypeConverter = (TypeConverter<Number>)
+ TypeConverterRegistry.getInstance().findCompatibleConverter(Number.class);
+ assertNotNull(numberTypeConverter);
+ // TODO: is there a specific converter this should return?
+ }
+
+ public enum Foo {
+ I, PITY, THE
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testFindEnumConverter() throws Exception {
+ final TypeConverter<Foo> fooTypeConverter = (TypeConverter<Foo>)
+ TypeConverterRegistry.getInstance().findCompatibleConverter(Foo.class);
+ assertNotNull(fooTypeConverter);
+ assertEquals(Foo.I, fooTypeConverter.convert("i"));
+ assertEquals(Foo.PITY, fooTypeConverter.convert("pity"));
+ assertEquals(Foo.THE, fooTypeConverter.convert("THE"));
+ }
+
+ public static final class CustomTestClass1 {
+
+ private CustomTestClass1() {}
+
+ }
+
+ @Plugin(name = "CustomTestClass1Converter1", category = TypeConverters.CATEGORY)
+ public static final class CustomTestClass1Converter1
+ implements TypeConverter<CustomTestClass1> {
+
+ @Override
+ public CustomTestClass1 convert(final String ignored) {
+ return new CustomTestClass1();
+ }
+
+ }
+
+ @SuppressWarnings("ComparableType")
+ @Plugin(name = "CustomTestClass1Converter2", category = TypeConverters.CATEGORY)
+ public static final class CustomTestClass1Converter2
+ implements TypeConverter<CustomTestClass1>, Comparable<TypeConverter<?>> {
+
+ @Override
+ public CustomTestClass1 convert(final String ignored) {
+ return new CustomTestClass1();
+ }
+
+ @Override
+ public int compareTo(@SuppressWarnings("NullableProblems") final TypeConverter<?> converter) {
+ return -1;
+ }
+
+ }
+
+ @Test
+ public void testMultipleComparableConverters() {
+ final TypeConverter<?> converter = TypeConverterRegistry
+ .getInstance()
+ .findCompatibleConverter(CustomTestClass1.class);
+ assertThat(converter, instanceOf(CustomTestClass1Converter2.class));
+ }
+
+ public static final class CustomTestClass2 {
+
+ private CustomTestClass2() {}
+
+ }
+
+ @Plugin(name = "CustomTestClass2Converter1", category = TypeConverters.CATEGORY)
+ public static final class CustomTestClass2Converter1
+ implements TypeConverter<CustomTestClass2> {
+
+ @Override
+ public CustomTestClass2 convert(final String ignored) {
+ return new CustomTestClass2();
+ }
+
+ }
+
+ @Plugin(name = "CustomTestClass2Converter2", category = TypeConverters.CATEGORY)
+ public static final class CustomTestClass2Converter2
+ implements TypeConverter<CustomTestClass2> {
+
+ @Override
+ public CustomTestClass2 convert(final String ignored) {
+ return new CustomTestClass2();
+ }
+
+ }
+
+ @Test
+ public void testMultipleIncomparableConverters() {
+ final TypeConverter<?> converter = TypeConverterRegistry
+ .getInstance()
+ .findCompatibleConverter(CustomTestClass2.class);
+ assertThat(converter, instanceOf(CustomTestClass2Converter1.class));
+ }
+
+}
diff --cc log4j-plugins/src/main/java/module-info.java
index 37820a4,0000000..20f1f17
mode 100644,000000..100644
--- a/log4j-plugins/src/main/java/module-info.java
+++ b/log4j-plugins/src/main/java/module-info.java
@@@ -1,34 -1,0 +1,36 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+module org.apache.logging.log4j.plugins {
+ exports org.apache.logging.log4j.plugins;
+ exports org.apache.logging.log4j.plugins.convert;
++ exports org.apache.logging.log4j.plugins.di;
++ exports org.apache.logging.log4j.plugins.di.model;
+ exports org.apache.logging.log4j.plugins.processor;
+ exports org.apache.logging.log4j.plugins.util;
+ exports org.apache.logging.log4j.plugins.validation;
+ exports org.apache.logging.log4j.plugins.validation.constraints;
+ exports org.apache.logging.log4j.plugins.validation.validators;
+ exports org.apache.logging.log4j.plugins.bind;
+ exports org.apache.logging.log4j.plugins.inject;
+ exports org.apache.logging.log4j.plugins.name;
+
- requires java.compiler;
+ requires org.apache.logging.log4j;
+ requires transitive org.osgi.framework;
+
+ uses org.apache.logging.log4j.plugins.processor.PluginService;
++ provides org.apache.logging.log4j.plugins.processor.PluginService with org.apache.logging.log4j.plugins.convert.plugins.Log4jPlugins;
+}