How to configure log4j for an xtext gradle build?

209 views Asked by At

When I start the gradle build in one of my modules, it prints an error-message to std-error:

:m28_presentation_api:generateXtext
Error initializing JvmElement

That's not very helpful and I hope, that I can configure log4j to print more details about the exception. I think this message is logged by JvmTypesBuilder.initializeSafely()

LOG.error("Error initializing JvmElement", e);

Versions:

According to the log4j V1 docs, it should be enough when I add a log4j.properties file to the classpath: so I just save this file in src/main/java.
But it seems that this is not used/found - or maybe I did something wrong in the configuration file:

log4j.rootLogger=stderr
log4j.appender.stderr=org.apache.log4j.ConsoleAppender
log4j.appender.stderr.layout=org.apache.log4j.PatternLayout
# Pattern to output the caller's file name and line number.
log4j.appender.stderr.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

When I now start the build, I'd expect a different log-output for the error-message, but it prints the same message as before. So obviously my log-config is not used for some reasons.

What am I missing?
Or can someone maybe point me to an example project?

2

There are 2 answers

1
Christian Dietrich On

it looks like LOG.error() does not print a stacktrace by default. maybe you can actively change your code e.g.

class MyDslJvmModelInferrer extends AbstractModelInferrer {

    @Inject extension JvmTypesBuilder

    private static Logger LOG = Logger.getLogger(MyDslJvmModelInferrer);


    def dispatch void infer(Model element, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
        acceptor.accept(element.toClass(element.name, [
            try {
                throw new IllegalArgumentException("mimimi")

            } catch (Exception e) {
                e.printStackTrace
                throw e
            }
        ]))
    }
}
0
TmTron On

This is not really an answer, but a workaround (maybe helpful for others).

I gave up on the log4j configuration after wasting some hours and applied this workaround which took only some minutes and revealed the real problem.

What I've done, is to create my own JvmTypesBuilder, override the initializeSafely method and directly print the stack-trace to stderr:

import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder
import org.eclipse.emf.ecore.EObject
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1
import org.apache.log4j.Logger

class JvmTypesBuilderTm extends JvmTypesBuilder {

    private static Logger LOG = Logger.getLogger(JvmTypesBuilder)

    // TODO: nasty workaround because I cannot figure out how to configure the logging correctly
    override <T extends EObject> initializeSafely(T targetElement, Procedure1<? super T> initializer) {
        if(targetElement !== null && initializer !== null) {
            try {
                initializer.apply(targetElement);
            } catch (Exception e) {
                LOG.error("Error initializing JvmElement: "+targetElement.toString, e);
                e.printStackTrace
            }
        }
        return targetElement;
    }
}

Then I just replaced all occurrences of the JvmTypesBuilder in my code with the new one. With the stacktrace, it was easy to find the real issue in my code.