我没有成功尝试将其转换为Kotlin并使用它。
它可以像Java一样工作,但不能与我的Kotlin(我使用IntelliJ Kotlin插件进行转换)一起使用
问题似乎出在这部分
@PluginFactory
public static AnsiConsoleAppender createAppender(
我尝试添加@JvmStatic,但出现此错误:
无法为元素AnsiConsoleAppender调用类AnsiConsoleAppender中的工厂方法:java.lang.IllegalArgumentException:指定为非null的参数为null:方法AnsiConsoleAppender $ Companion.AnsiConsoleAppender,参数过滤器java.lang.reflect.InvocationTargetException
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AbstractAppender;
import org.apache.logging.log4j.core.appender.AppenderLoggingException;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.layout.PatternLayout;
import java.io.Serializable;
/**
* <h2>AnsiConsoleAppender</h2>
*
* <h3>notes</h3>
* <li>class name need not match the @Plugin name</li>
* <h3>more<h3/>
* <li><a href="https://stackoverflow.com/a/24220688/270143">How to Create a Custom Appender in log4j2?</a></li>
*/
@Plugin(name="AnsiConsoleAppender", category="Core", elementType="appender", printObject=true)
public final class AnsiConsoleAppender extends AbstractAppender {
protected AnsiConsoleAppender(String name, Filter filter,
Layout<? extends Serializable> layout, final boolean ignoreExceptions) {
super(name, filter, layout, ignoreExceptions);
}
// The append method is where the appender does the work.
// Given a log event, you are free to do with it what you want.
// This example demonstrates:
// 1. Concurrency: this method may be called by multiple threads concurrently
// 2. How to use layouts
// 3. Error handling
//@Override
public void append(LogEvent event) {
try {
final byte[] bytes = getLayout().toByteArray(event);
// output code goes here
} catch (Exception ex) {
if (!ignoreExceptions()) throw new AppenderLoggingException(ex);
}
}
// Your custom appender needs to declare a factory method
// annotated with `@PluginFactory`. Log4j will parse the configuration
// and call this factory method to construct an appender instance with
// the configured attributes.
@PluginFactory
public static AnsiConsoleAppender createAppender(
@PluginAttribute("name") String name,
@PluginElement("Layout") Layout<? extends Serializable> layout,
@PluginElement("Filter") final Filter filter,
@PluginAttribute("otherAttribute") String otherAttribute) {
if (name == null) {
LOGGER.error("No name provided for AnsiConsoleAppenderImpl");
return null;
}
if (layout == null) {
layout = PatternLayout.createDefaultLayout();
}
return new AnsiConsoleAppender(name, filter, layout, true);
}
}
import org.apache.logging.log4j.core.AbstractLifeCycle
import org.apache.logging.log4j.core.Filter
import org.apache.logging.log4j.core.Layout
import org.apache.logging.log4j.core.LogEvent
import org.apache.logging.log4j.core.appender.AbstractAppender
import org.apache.logging.log4j.core.appender.AppenderLoggingException
import org.apache.logging.log4j.core.config.plugins.Plugin
import org.apache.logging.log4j.core.config.plugins.PluginAttribute
import org.apache.logging.log4j.core.config.plugins.PluginElement
import org.apache.logging.log4j.core.config.plugins.PluginFactory
import org.apache.logging.log4j.core.layout.PatternLayout
import java.io.Serializable
@Plugin(name = "AnsiConsoleAppender", category = "Core", elementType = "appender", printObject = true)
class AnsiConsoleAppender /*protected*/ constructor(
name: String, filter: Filter,
layout: Layout<out Serializable>, ignoreExceptions: Boolean
) : AbstractAppender(name, filter, layout, ignoreExceptions) {
// The append method is where the appender does the work.
// Given a log event, you are free to do with it what you want.
// This example demonstrates:
// 1. Concurrency: this method may be called by multiple threads concurrently
// 2. How to use layouts
// 3. Error handling
//@Override
override fun append(event: LogEvent) {
try {
val bytes = layout.toByteArray(event)
//AnsiColor.out(String(bytes), ColorMaps.ASTERIKSY, null, true)
} catch (ex: Exception) {
if (!ignoreExceptions()) throw AppenderLoggingException(ex)
}
}
companion object {
// Your custom appender needs to declare a factory method
// annotated with `@PluginFactory`. Log4j will parse the configuration
// and call this factory method to construct an appender instance with
// the configured attributes.
@JvmStatic
@PluginFactory
fun createAppender(
@PluginAttribute("name") name: String?,
@PluginElement("Layout") layout: Layout<out Serializable>?,
@PluginElement("Filter") filter: Filter,
@PluginAttribute("otherAttribute") otherAttribute: String
): AnsiConsoleAppender? {
val lay = layout ?: PatternLayout.createDefaultLayout()
if (name == null) {
AbstractLifeCycle.LOGGER.error("No name provided for AnsiConsoleAppenderImpl")
return null
}
return AnsiConsoleAppender(name, filter, lay, true)
}
}
}
我想念什么?
答案 0 :(得分:1)
该异常表明filter
为空。
因此它应该是可为空的类型。
companion object {
@PluginFactory
@JvmStatic
fun createAppender(
@PluginAttribute("name") name: String,
@PluginElement("Layout") layout: Layout<out Serializable>,
@PluginElement("Filter") filter: Filter?,
@PluginAttribute("otherAttribute") otherAttribute: String?
): AnsiConsoleAppender {
答案 1 :(得分:0)
在Kotlin工厂中,方法通常是在类的伴侣对象中定义的,例如:
class AnsiConsoleAppender : AbstractAppender() {
companion object {
// add JvmStatic annotation if you want to call this method from Java file
@JvmStatic
@PluginFactory
fun createAppender(/*params*/): AnsiConsoleAppender {
//...
}
}
}