将包含静态工厂方法的Java类转换为Kotlin时遇到问题

时间:2019-01-26 12:35:35

标签: kotlin log4j2

我没有成功尝试将其转换为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)
        }
    }
}

我想念什么?

2 个答案:

答案 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 {
            //...
        }
    }
}

More on companion object