diff --git a/pages/docs/compiler.md b/pages/docs/compiler.md
index 86f15b7cdb2fcee74dc9d63f9bfa64cee2e8f62f..d60822b10956accb9313f4a1b677574996a2e198 100644
--- a/pages/docs/compiler.md
+++ b/pages/docs/compiler.md
@@ -4,7 +4,7 @@ The compiler is JastAdd-compliant, i.e., it accepts all flags available for Jast
 Additional options are as follows.
 
 | Name | Required (Default) | Description |
-|-|-|-|
+|---|---|---|
 | `--rootNode` | Yes | Root node in the base grammar. |
 | `--protocols` | No (`mqtt`) | Protocols to enable, currently available: `mqtt, rest`. |
 | `--printYaml` | No (false) | Print out YAML instead of generating files. |
@@ -12,14 +12,15 @@ Additional options are as follows.
 | `--logReads` | No (false) | Enable logging for every received message. |
 | `--logWrites` | No (false) | Enable logging for every sent message. |
 | `--logIncremental` | No (false) | Enable logging for observer in incremental dependency tracking. |
+| `--logTarget` | No (`console`) | Logging target to use, currently available: `console, slf4j`. |
 | `--experimental-jastadd-329` | No (false) | Use trace events `INC_FLUSH_START` and `INC_FLUSH_END` ([JastAdd issue #329][jastadd-issue-329]), see [section about automatic dependency tracking](/using#dependency-tracking-automatically-derived). |
 | `--incremental` | No (false) | Enables incremental dependency tracking (if `trace` is also set appropriately). |
 | `--trace[=flush]` | No (false) | Enables incremental dependency tracking (if `incremental` is also set appropriately). |
 | `--version` | No (false) | Print version info and exit (reused JastAdd option) |
 | `--o` | No (`.`) | Output directory (reused JastAdd option) |
 
-All files to be process have to be passed as arguments.
-Their type is decided by the file extension (`ast` and `relast` for input grammars, `connect` and `ragconnect` for RagConnect definitions file).
+All files to be processed have to be passed as arguments.
+Their type is deduced by the file extension (`ast` and `relast` for input grammars, `connect` and `ragconnect` for RagConnect definitions file).
 
 # Additional software dependencies
 
@@ -52,7 +53,7 @@ However, depending on the selected protocols and/or used features, additional de
 - Additional remarks:
     - Host is always `localhost`.
     - Might work with newer versions of `com.sparkjava.spark-core` as well.
-    - For debugging, it is beneficial to include an implementation for [SLF4J](http://www.slf4j.org/).
+    - For debugging, it is beneficial to include an implementation for [SLF4J][slf4j].
 
 ## Used features
 
@@ -91,5 +92,15 @@ However, depending on the selected protocols and/or used features, additional de
 - Remarks:
     - [Feature description](/using#an-advanced-example)
 
+### Logging Target SLF4J
+
+- Condition: When using `--logTarget=slf4j` to RagConnect
+- Required runtime dependencies:
+  - `group: 'org.slf4j', name: 'slf4j-api', version: '1.7.0'`
+- Required options for RelAST compiler: _none_
+- Required options for JastAdd: _none_
+- Remarks:
+  - Additionally, a slf4j binding is required, see [the slf4j user manual][slf4j]
 
 [jastadd-issue-329]: https://bitbucket.org/jastadd/jastadd2/issues/329/add-event-for-completion-of-flush
+[slf4j]: https://www.slf4j.org/manual.html
diff --git a/ragconnect.base/src/main/jastadd/Intermediate.jadd b/ragconnect.base/src/main/jastadd/Intermediate.jadd
index 47f3aa473e0959ece3a24b684b98b59893c58413..5ca17cdc4ca04db353dbf073fc0cff3d8dd7df93 100644
--- a/ragconnect.base/src/main/jastadd/Intermediate.jadd
+++ b/ragconnect.base/src/main/jastadd/Intermediate.jadd
@@ -17,6 +17,24 @@ aspect SharedMustache {
 
   syn String RagConnect.internalRagConnectPrefix() = "_ragconnect_";
 
+  syn String RagConnect.logDebug() = logStatement("debug");
+  syn String RagConnect.logInfo() = logStatement("info");
+  syn String RagConnect.logWarn() = logStatement("warn");
+  syn String RagConnect.logError() = logStatement("error");
+  syn String RagConnect.logException() = logStatement("exception");
+  syn String RagConnect.log_() {
+    switch (getConfiguration().getLoggingTarget()) {
+      //noinspection ConstantConditions
+      case "console":
+        return "%s";
+      //noinspection ConstantConditions
+      case "slf4j":
+        return "{}";
+      default:
+        return "?";
+    }
+  }
+
   syn String RagConnect.observerInstanceSingletonMethodName() = internalRagConnectPrefix() + "Observer";
   syn String RagConnect.observerInstanceResetMethodName() = internalRagConnectPrefix() + "resetObserver";
 
@@ -30,6 +48,31 @@ aspect SharedMustache {
   syn boolean EndpointDefinition.typeIsOpt() = getEndpointTarget().typeIsOpt();
 
   // === attributes needed for computing above ones ===
+  syn String RagConnect.logStatement(String level) {
+    switch (getConfiguration().getLoggingTarget()) {
+      //noinspection ConstantConditions
+      case "console":
+        switch (level) {
+          case "debug":
+          case "info":
+            return "ASTNode." + logConsoleOut();
+          case "warn":
+          case "error":
+          case "exception":
+            return "ASTNode." + logConsoleErr();
+          default:
+            return "unknownLoggingLevelForConsole_" + level + "_";
+        }
+      //noinspection ConstantConditions
+      case "slf4j":
+        if (level.equals("exception")) {
+          level = "error";
+        }
+        return "org.slf4j.LoggerFactory.getLogger(getClass())." + level;
+      default:
+        return "unknownLoggingOptionGiven_" + getConfiguration().getLoggingTarget() + "_";
+    }
+  }
   syn boolean EndpointTarget.typeIsList() = false;
   eq TypeEndpointTarget.typeIsList() {
     return getType().isListComponent();
@@ -237,6 +280,9 @@ aspect MustacheRagConnect {
 
   syn String RagConnect.observerInstanceFieldName() = internalRagConnectPrefix() + "ObserverInstance";
 
+  syn String RagConnect.logConsoleOut() = internalRagConnectPrefix() + "logStdOut";
+  syn String RagConnect.logConsoleErr() = internalRagConnectPrefix() + "logStdErr";
+
   syn java.util.List<Component> TypeDecl.tokenComponents() {
     return filteredComponents(Component::isTokenComponent);
   }
diff --git a/ragconnect.base/src/main/jastadd/RagConnect.relast b/ragconnect.base/src/main/jastadd/RagConnect.relast
index f6cf0dd68708157aa291b6b0b50077b2fe72034c..5605324e99fd6206f4dc4c7eb3a92da3342e224d 100644
--- a/ragconnect.base/src/main/jastadd/RagConnect.relast
+++ b/ragconnect.base/src/main/jastadd/RagConnect.relast
@@ -30,12 +30,13 @@ JavaMappingDefinitionType : MappingDefinitionType ::= Type:JavaTypeUse;
 JavaArrayMappingDefinitionType : MappingDefinitionType ::= Type:JavaTypeUse;
 DefaultMappingDefinition : MappingDefinition;
 
-Handler ::= <DefinitionFileName> <ClassName> <UniqueName> <InUse:boolean>;
+Handler ::= <ClassName> <UniqueName> <InUse:boolean>;
 
 Configuration ::=
 <LoggingEnabledForReads:boolean>
 <LoggingEnabledForWrites:boolean>
 <LoggingEnabledForIncremental:boolean>
+<LoggingTarget:String>
 <JastAddList:String>
 <JastAddOpt:String>
 <IncrementalOptionActive:boolean>
diff --git a/ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java b/ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java
index d8c9c550d183416e353900e97b6629383b31016e..dfe3f9789681b3dee17c7fec7b2c671ef400808c 100644
--- a/ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java
+++ b/ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java
@@ -9,18 +9,19 @@ import org.jastadd.ragconnect.scanner.RagConnectScanner;
 import org.jastadd.relast.compiler.AbstractCompiler;
 import org.jastadd.relast.compiler.CompilerException;
 
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
-import java.nio.file.StandardCopyOption;
-import java.util.*;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import java.util.Collection;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
 
 public class Compiler extends AbstractCompiler {
 
-  //  private ValueOption optionOutputDir;
   private ValueOption optionRootNode;
   private ValueOption optionProtocols;
   private BooleanOption optionPrintYaml;
@@ -28,13 +29,15 @@ public class Compiler extends AbstractCompiler {
   private BooleanOption optionLogReads;
   private BooleanOption optionLogWrites;
   private BooleanOption optionLogIncremental;
+  private ValueOption optionLogTarget;
   private BooleanOption optionExperimentalJastAdd329;
 
+  private static final String OPTION_LOGGING_TARGET_CONSOLE = "console";
+  private static final String OPTION_LOGGING_TARGET_SLF4J = "slf4j";
+
   private static final String OPTION_PROTOCOL_MQTT = "mqtt";
   private static final String OPTION_PROTOCOL_REST = "rest";
 
-  private final static Logger LOGGER = Logger.getLogger(Compiler.class.getName());
-
   public Compiler() {
     super("ragconnect", true);
   }
@@ -58,11 +61,8 @@ public class Compiler extends AbstractCompiler {
       getConfiguration().printHelp(System.out);
       return;
     }
-    if (optionVerbose.value()) {
-      LOGGER.setLevel(Level.FINE);
-    }
 
-    LOGGER.info(() -> "Running RagConnect " + readVersion());
+    System.out.println("Running RagConnect " + readVersion());
 
     if (!getConfiguration().outputDir().exists()) {
       try {
@@ -88,35 +88,21 @@ public class Compiler extends AbstractCompiler {
       for (ErrorMessage e : ragConnect.errors()) {
         sb.append(e).append("\n");
       }
-      LOGGER.severe(sb::toString);
+      System.err.println(sb);
       System.exit(1);
     }
 
     if (optionPrintYaml.value()) {
       String yamlContent = ragConnect.toYAML().prettyPrint();
-      LOGGER.fine(yamlContent);
+      if (isVerbose()) {
+        System.out.println(yamlContent);
+      }
       writeToFile(getConfiguration().outputDir().toPath().resolve("RagConnect.yml"), yamlContent);
       return;
     }
 
-    LOGGER.fine("Writing output files");
-    // copy handlers into outputDir
-    for (Handler handler : ragConnect.getHandlerList()) {
-      if (!handler.getInUse()) {
-        continue;
-      }
-      String handlerFileName = handler.getDefinitionFileName();
-      try {
-        InputStream inputStream = Compiler.class.getClassLoader().getResourceAsStream(handlerFileName);
-        if (inputStream == null) {
-          throw new CompilerException("Could not open " + handlerFileName);
-        }
-        Files.copy(inputStream,
-            getConfiguration().outputDir().toPath().resolve(handlerFileName),
-            StandardCopyOption.REPLACE_EXISTING);
-      } catch (IOException e) {
-        throw new CompilerException("Could not copy " + handlerFileName, e);
-      }
+    if (isVerbose()) {
+      System.out.println("Writing output files");
     }
     for (GrammarFile grammarFile : ragConnect.getProgram().getGrammarFileList()) {
       Path outputFile = getConfiguration().outputDir().toPath().resolve(grammarFile.getFileName());
@@ -133,14 +119,22 @@ public class Compiler extends AbstractCompiler {
 
   public static void main(String[] args) {
     System.setProperty("mustache.debug", "true");
+    Compiler compiler = new Compiler();
     try {
-      new Compiler().run(args);
+      compiler.run(args);
     } catch (CompilerException e) {
-      LOGGER.log(Level.SEVERE, e.getMessage(), e);
+      System.err.println(e.getMessage());
+      if (compiler.isVerbose()) {
+        e.printStackTrace();
+      }
       System.exit(1);
     }
   }
 
+  private boolean isVerbose() {
+    return optionVerbose != null && optionVerbose.value();
+  }
+
   /**
    * Reads the version string.
    * <p>
@@ -196,6 +190,11 @@ public class Compiler extends AbstractCompiler {
     optionLogIncremental = addOption(
         new BooleanOption("logIncremental", "Enable logging for observer in incremental dependency tracking.")
             .defaultValue(false));
+    optionLogTarget = addOption(
+            new ValueOption("logTarget", "Logging target to use")
+                    .addDefaultValue(OPTION_LOGGING_TARGET_CONSOLE, "Use std out and std err")
+                    .addAcceptedValue(OPTION_LOGGING_TARGET_SLF4J, "Use SLF4J API")
+    );
     optionExperimentalJastAdd329 = addOption(
         new BooleanOption("experimental-jastadd-329", "Use trace events INC_FLUSH_START and INC_FLUSH_END (JastAdd issue #329).")
             .defaultValue(false));
@@ -218,13 +217,13 @@ public class Compiler extends AbstractCompiler {
       switch (extension) {
         case "ast":
         case "relast":
-          // processGrammar
+          // process grammar
           program.addGrammarFile(parseGrammar(filename));
           atLeastOneGrammar = true;
           break;
         case "connect":
         case "ragconnect":
-          // process ragConnect
+          // process RagConnect specification
           ragConnect.addConnectSpecificationFile(parseConnectSpec(filename));
           atLeastOneRagConnect = true;
           break;
@@ -232,13 +231,13 @@ public class Compiler extends AbstractCompiler {
           throw new CompilerException("Unknown file extension " + extension + " in " + filename);
       }
     }
-    if (!atLeastOneGrammar) {
-      LOGGER.severe(() -> "No grammar file specified! (*.ast, *.relast)");
-    }
+
     if (!atLeastOneRagConnect) {
-      LOGGER.severe(() -> "No ragconnect file specified! (*.connect, *.ragconnect)");
+      System.err.println("No RagConnect specification file (*.connect, *.ragconnect) specified!");
     }
-    if (!atLeastOneGrammar && !atLeastOneRagConnect) {
+    if (!atLeastOneGrammar) {
+      // without a grammar, RagConnect can not operate
+      System.err.println("No grammar file (*.ast, *.relast) specified! Exiting!");
       System.exit(1);
     }
 
@@ -246,6 +245,7 @@ public class Compiler extends AbstractCompiler {
     ragConnect.flushTreeCache();
     ragConnect.treeResolveAll();
 
+    // add new parts to production rule, and new relations
     ragConnect.additionalRelations().forEach(ragConnectGrammarPart::addDeclaration);
     ragConnect.additionalTokens().forEach(TypeDecl::addComponent);
 
@@ -257,8 +257,8 @@ public class Compiler extends AbstractCompiler {
       RagConnectScanner scanner = new RagConnectScanner(reader);
       RagConnectParser parser = new RagConnectParser();
       GrammarFile grammarFile = (GrammarFile) parser.parse(scanner);
-      if (optionVerbose.value()) {
-        LOGGER.fine(grammarFile::dumpTree);
+      if (isVerbose()) {
+        System.out.println(grammarFile.dumpTree());
       }
       grammarFile.setFileName(toBaseName(filename));
       return grammarFile;
@@ -298,12 +298,15 @@ public class Compiler extends AbstractCompiler {
     ragConnect.getConfiguration().setLoggingEnabledForReads(optionLogReads.value());
     ragConnect.getConfiguration().setLoggingEnabledForWrites(optionLogWrites.value());
     ragConnect.getConfiguration().setLoggingEnabledForIncremental(optionLogIncremental.value());
+    ragConnect.getConfiguration().setLoggingTarget(optionLogTarget.value());
     ragConnect.getConfiguration().setExperimentalJastAdd329(optionExperimentalJastAdd329.value());
 
     // reuse "--incremental" and "--trace=flush" options of JastAdd
     boolean incrementalOptionActive = this.getConfiguration().incremental() && this.getConfiguration().traceFlush();
     ragConnect.getConfiguration().setIncrementalOptionActive(incrementalOptionActive);
-    LOGGER.fine(() -> "ragConnect.getConfiguration().IncrementalOptionActive = " + incrementalOptionActive);
+    if (isVerbose()) {
+      System.out.println("ragConnect.getConfiguration().IncrementalOptionActive = " + incrementalOptionActive);
+    }
 
     // reuse "--List" and "--Opt" options of JastAdd
     ragConnect.getConfiguration().setJastAddList(this.getConfiguration().listType());
@@ -319,12 +322,13 @@ public class Compiler extends AbstractCompiler {
     ragConnect.getConfiguration().setRootNode(rootNode);
 
     // Handler ::= <ClassName> <UniqueName> <InUse:boolean>;
-    ragConnect.addHandler(new Handler("MqttHandler.jadd", "MqttServerHandler", "mqtt", optionProtocols.hasValue(OPTION_PROTOCOL_MQTT)));
-    ragConnect.addHandler(new Handler("RestHandler.jadd", "RestServerHandler", "rest", optionProtocols.hasValue(OPTION_PROTOCOL_REST)));
+    ragConnect.addHandler(new Handler("MqttServerHandler", "mqtt", optionProtocols.hasValue(OPTION_PROTOCOL_MQTT)));
+    ragConnect.addHandler(new Handler("RestServerHandler", "rest", optionProtocols.hasValue(OPTION_PROTOCOL_REST)));
   }
 
   public String generateAspect(RagConnect ragConnect) {
     StringBuilder sb = new StringBuilder();
+    // add handler to get error message when template expansion did not find some part
     com.github.mustachejava.reflect.ReflectionObjectHandler roh = new com.github.mustachejava.reflect.ReflectionObjectHandler() {
       @Override
       public com.github.mustachejava.Binding createBinding(String name, final com.github.mustachejava.TemplateContext tc, com.github.mustachejava.Code code) {
@@ -349,7 +353,7 @@ public class Compiler extends AbstractCompiler {
 
   @Override
   protected int error(String message) {
-    LOGGER.log(Level.SEVERE, message);
+    System.err.println(message);
     return 1;
   }
 
diff --git a/ragconnect.base/src/main/resources/MqttHandler.jadd b/ragconnect.base/src/main/resources/MqttHandler.mustache
similarity index 92%
rename from ragconnect.base/src/main/resources/MqttHandler.jadd
rename to ragconnect.base/src/main/resources/MqttHandler.mustache
index 0651d5fa84940f16ea6ff2ba1c674b477e509fe8..d5a83a04d89e67ecc09e45c0487bd37e516fd9ad 100644
--- a/ragconnect.base/src/main/resources/MqttHandler.jadd
+++ b/ragconnect.base/src/main/resources/MqttHandler.mustache
@@ -1,4 +1,3 @@
-aspect MqttHandler {
 public class MqttServerHandler {
   private final java.util.Map<String, MqttHandler> handlers = new java.util.HashMap<>();
   private final java.util.Map<RagConnectToken, java.util.function.BiConsumer<String, byte[]>> tokensForRemoval = new java.util.HashMap<>();
@@ -90,7 +89,6 @@ public class MqttHandler {
   }
   private static final int DEFAULT_PORT = 1883;
 
-  private final org.apache.logging.log4j.Logger logger;
   private final String name;
 
   /** The host running the MQTT broker. */
@@ -112,7 +110,6 @@ public class MqttHandler {
 
   public MqttHandler(String name) {
     this.name = java.util.Objects.requireNonNull(name, "Name must be set");
-    this.logger = org.apache.logging.log4j.LogManager.getLogger(MqttHandler.class);
     this.normalCallbacks = new java.util.HashMap<>();
     this.wildcardCallbacks = new java.util.ArrayList<>();
     this.readyLatch = new java.util.concurrent.CountDownLatch(1);
@@ -149,7 +146,7 @@ public class MqttHandler {
     java.util.Objects.requireNonNull(host, "Host need to be set!");
 
     this.host = java.net.URI.create("tcp://" + host + ":" + port);
-    logger.debug("Host for {} is {}", this.name, this.host);
+    {{logDebug}}("Host for {{log_}} is {{log_}}", this.name, this.host);
 
     org.fusesource.mqtt.client.MQTT mqtt = new org.fusesource.mqtt.client.MQTT();
     mqtt.setHost(this.host);
@@ -159,12 +156,12 @@ public class MqttHandler {
     // add the listener to dispatch messages later
     connection.listener(new org.fusesource.mqtt.client.ExtendedListener() {
       public void onConnected() {
-        logger.debug("Connected");
+        {{logDebug}}("Connected");
       }
 
       @Override
       public void onDisconnected() {
-        logger.debug("Disconnected");
+        {{logDebug}}("Disconnected");
       }
 
       @Override
@@ -172,10 +169,10 @@ public class MqttHandler {
                             org.fusesource.hawtbuf.Buffer body,
                             org.fusesource.mqtt.client.Callback<org.fusesource.mqtt.client.Callback<Void>> ack) {
         // this method is called, whenever a MQTT message is received
-        String topicString = topic.toString();
+        final String topicString = topic.toString();
         java.util.List<java.util.function.BiConsumer<String, byte[]>> callbackList = callbacksFor(topicString);
         if (callbackList.isEmpty()) {
-          logger.debug("Got a message at {}, but no callback to call. Forgot to subscribe?", topic);
+          {{logDebug}}("Got a message at {{log_}}, but no callback to call. Forgot to subscribe?", topic);
         } else {
           byte[] message = body.toByteArray();
           for (java.util.function.BiConsumer<String, byte[]> callback : callbackList) {
@@ -183,7 +180,7 @@ public class MqttHandler {
               astLock.lock();
               callback.accept(topicString, message);
             } catch (Exception e) {
-              logger.catching(e);
+              {{logException}}("Exception in callback for " + topicString, e);
             } finally {
               astLock.unlock();
             }
@@ -197,7 +194,7 @@ public class MqttHandler {
                             org.fusesource.hawtbuf.Buffer body,
                             Runnable ack) {
         // not used by this type of connection
-        logger.warn("onPublish should not be called");
+        {{logWarn}}("onPublish should not be called");
       }
 
       @Override
@@ -219,13 +216,13 @@ public class MqttHandler {
               new org.fusesource.mqtt.client.Callback<>() {
                 @Override
                 public void onSuccess(Void value) {
-                  logger.debug("success sending welcome message");
+                  {{logDebug}}("success sending welcome message");
                   setReady();
                 }
 
             @Override
-            public void onFailure(Throwable value) {
-              logger.debug("failure sending welcome message", value);
+            public void onFailure(Throwable cause) {
+              {{logException}}("failure sending welcome message", cause);
             }
           });
         } else {
@@ -296,7 +293,7 @@ public class MqttHandler {
       return false;
     }
     // register callback
-    logger.debug("new connection for {}", topic);
+    {{logDebug}}("new connection for {{log_}}", topic);
     final boolean needSubscribe;
     if (isWildcardTopic(topic)) {
       String regex = regexForWildcardTopic(topic);
@@ -330,13 +327,13 @@ public class MqttHandler {
         connection.subscribe(topicArray, new org.fusesource.mqtt.client.Callback<>() {
           @Override
           public void onSuccess(byte[] qoses) {
-            logger.debug("Subscribed to {}, qoses: {}", topic, qoses);
+            {{logDebug}}("Subscribed to {{log_}}, qoses: {{log_}}", topic, qoses);
             operationFinished.countDown();
           }
 
           @Override
           public void onFailure(Throwable cause) {
-            logger.error("Could not subscribe to {}", topic, cause);
+            {{logException}}("Could not subscribe to " + topic, cause);
             success.set(false);
             operationFinished.countDown();
           }
@@ -403,7 +400,7 @@ public class MqttHandler {
     }
 
     if (topicToUnsubscribe == null) {
-      logger.warn("Disconnect for not connected topic '{}'", topic);
+      {{logWarn}}("Disconnect for not connected topic '{{log_}}'", topic);
       return false;
     }
 
@@ -422,7 +419,7 @@ public class MqttHandler {
           @Override
           public void onFailure(Throwable cause) {
             success.set(false);
-            logger.warn("Could not disconnect from {}", topic, cause);
+            {{logException}}("Could not disconnect from " + topic, cause);
             operationFinished.countDown();
           }
         });
@@ -433,7 +430,7 @@ public class MqttHandler {
           return false;
         }
       } catch (InterruptedException e) {
-        logger.catching(e);
+        {{logException}}("Interrupted while disconnecting from " + topic, e);
         success.set(false);
       }
     }
@@ -460,14 +457,14 @@ public class MqttHandler {
 
   public void close() {
     if (connection == null) {
-      logger.warn("Stopping without connection. Was setHost() called?");
+      {{logWarn}}("Stopping without connection. Was setHost() called?");
       return;
     }
     connection.getDispatchQueue().execute(() -> {
       connection.disconnect(new org.fusesource.mqtt.client.Callback<>() {
         @Override
         public void onSuccess(Void value) {
-          logger.info("Disconnected {} from {}", name, host);
+          {{logInfo}}("Disconnected {{log_}} from {{log_}}", name, host);
         }
 
         @Override
@@ -493,12 +490,12 @@ public class MqttHandler {
         connection.publish(topic, bytes, qos, retain, new org.fusesource.mqtt.client.Callback<>() {
           @Override
           public void onSuccess(Void value) {
-            logger.debug("Published some bytes to {}", topic);
+            {{logDebug}}("Published some bytes to {{log_}}", topic);
           }
 
           @Override
-          public void onFailure(Throwable value) {
-            logger.warn("Could not publish on topic '{}'", topic, value);
+          public void onFailure(Throwable cause) {
+            {{logException}}("Could not publish on topic " + topic, cause);
           }
         });
       });
@@ -507,4 +504,3 @@ public class MqttHandler {
     }
   }
 }
-}
diff --git a/ragconnect.base/src/main/resources/RestHandler.jadd b/ragconnect.base/src/main/resources/RestHandler.mustache
similarity index 85%
rename from ragconnect.base/src/main/resources/RestHandler.jadd
rename to ragconnect.base/src/main/resources/RestHandler.mustache
index 9187afdab7a15c0bd7dc10679991505874c8af61..25192af366bfd4da29ace5c11d661b8cc8fd0992 100644
--- a/ragconnect.base/src/main/resources/RestHandler.jadd
+++ b/ragconnect.base/src/main/resources/RestHandler.mustache
@@ -1,14 +1,9 @@
-import java.util.concurrent.TimeUnit;aspect RestHandler {
 public class RestServerHandler {
   private static final int DEFAULT_PORT = 4567;
   private final java.util.Map<Integer, RestHandler> handlers = new java.util.HashMap<>();
   private final java.util.Map<RagConnectToken, Object> tokensForRemoval = new java.util.HashMap<>();
   private String name;
 
-  public RestServerHandler() {
-    this("RagConnect");
-  }
-
   public RestServerHandler(String name) {
     this.name = name;
   }
@@ -39,7 +34,7 @@ public class RestServerHandler {
 
   public boolean disconnect(RagConnectToken connectToken) {
     RestHandler handler = resolveHandler(connectToken.uri);
-    return handler != null ? handler.disconnect(connectToken.uri.getPath(), tokensForRemoval.get(connectToken)) : false;
+    return handler != null && handler.disconnect(connectToken.uri.getPath(), tokensForRemoval.get(connectToken));
   }
 
   public void close() {
@@ -55,23 +50,13 @@ public class RestServerHandler {
 public class RestHandler {
   private static final int DEFAULT_PORT = 4567;
 
-  private final org.apache.logging.log4j.Logger logger;
-  private final String name;
   private int port;
-  private final java.util.concurrent.CountDownLatch exitCondition;
   /** Dispatch knowledge */
   private final java.util.Map<String, java.util.List<java.util.function.Consumer<String>>> callbacks;
   private final java.util.Map<String, SupplierWithException<String>> suppliers;
 
   public RestHandler() {
-    this("RagConnect");
-  }
-
-  public RestHandler(String name) {
-    this.logger = org.apache.logging.log4j.LogManager.getLogger(RestHandler.class);
-    this.name = name;
     this.port = DEFAULT_PORT;
-    this.exitCondition = new java.util.concurrent.CountDownLatch(1);
     this.callbacks = new java.util.HashMap<>();
     this.suppliers = new java.util.HashMap<>();
   }
@@ -111,7 +96,7 @@ public class RestHandler {
 
   public void newGETConnection(String path, SupplierWithException<String> supplier) {
     if (suppliers.get(path) != null) {
-      logger.warn("Overriding existing supplier for '{}'", path);
+      {{logWarn}}("Overriding existing supplier for '{{log_}}'", path);
     }
     suppliers.put(path, supplier);
     spark.Spark.get(path, (request, response) -> {
@@ -142,7 +127,7 @@ public class RestHandler {
   }
 
   private void start() {
-    logger.info("Starting REST server at {}", this.port);
+    {{logInfo}}("Starting REST server at {{log_}}", this.port);
     spark.Spark.port(this.port);
     spark.Spark.init();
     spark.Spark.awaitInitialization();
@@ -156,6 +141,5 @@ public class RestHandler {
 }
 @FunctionalInterface
 public interface SupplierWithException<T> {
-  public T get() throws Exception;
-}
+  T get() throws Exception;
 }
diff --git a/ragconnect.base/src/main/resources/handleUri.mustache b/ragconnect.base/src/main/resources/handleUri.mustache
index ff0ea7af7f920ac09a14de75a4afe1882540ac94..2312cd6983822c0e0b2987459047b7ca2a277fc2 100644
--- a/ragconnect.base/src/main/resources/handleUri.mustache
+++ b/ragconnect.base/src/main/resources/handleUri.mustache
@@ -6,18 +6,18 @@ try {
   host = uri.getHost();
   path = uri.getPath() + (uri.getFragment() != null ? "#" : "");
 } catch (java.net.URISyntaxException e) {
-  System.err.println(e.getMessage());  // Maybe re-throw error?
+  {{logError}}(e.getMessage());  // Maybe re-throw error?
   return false;
 }
 if (scheme == null || scheme.isBlank()) {
-  System.err.println("Missing or empty scheme in " + uri);
+  {{logError}}("Missing or empty scheme in " + uri);
   return false;
 }
 if (host == null || host.isBlank()) {
-  System.err.println("Missing or empty host in " + uri);
+  {{logError}}("Missing or empty host in " + uri);
   return false;
 }
 if (path == null || path.isBlank()) {
-  System.err.println("Missing or empty path in " + uri);
+  {{logError}}("Missing or empty path in " + uri);
   return false;
 }
diff --git a/ragconnect.base/src/main/resources/handler.mustache b/ragconnect.base/src/main/resources/handler.mustache
index 0d368731fd37454d5ea3982ebd2a3e2d03c8f047..49194266f96e84a4c24bc0987b83647082132dc2 100644
--- a/ragconnect.base/src/main/resources/handler.mustache
+++ b/ragconnect.base/src/main/resources/handler.mustache
@@ -25,8 +25,15 @@ aspect RagConnectHandler {
     {{fieldName}}.setupWaitUntilReady(time, unit);
   }
   {{/InUse}}
+{{> MqttHandler}}
 {{/mqttHandler}}
 
+{{#restHandler}}
+  {{#InUse}}
+{{> RestHandler}}
+  {{/InUse}}
+{{/restHandler}}
+
   class RagConnectToken {
     static java.util.concurrent.atomic.AtomicLong counter = new java.util.concurrent.atomic.AtomicLong(0);
     final long id;
@@ -81,7 +88,7 @@ aspect RagConnectHandler {
       if (errorMessage == null) {
         return true;
       } else {
-        System.err.println(errorMessage);
+        {{logWarn}}(errorMessage);
         return false;
       }
     }
@@ -145,7 +152,9 @@ aspect RagConnectHandler {
       }
       if (!result) {
         // only print error message, if all publishers failed to remove the token
-        errorMessages.stream().forEachOrdered(System.err::println);
+        for (String message : errorMessages) {
+          {{logError}}(message);
+        }
       }
       return result;
     }
diff --git a/ragconnect.base/src/main/resources/ragconnect.mustache b/ragconnect.base/src/main/resources/ragconnect.mustache
index dc6b839a87050d3993cd1bf6f19ffe3694d16242..ac7b906067f5f9ecd4a2bf0c51a368797f55dfbc 100644
--- a/ragconnect.base/src/main/resources/ragconnect.mustache
+++ b/ragconnect.base/src/main/resources/ragconnect.mustache
@@ -67,6 +67,24 @@ aspect RagConnect {
 
   {{> ListAspect}}
 
+  static void ASTNode.{{logConsoleOut}}(String message, Object... args) {
+    System.out.println(String.format(message, args));
+  }
+
+  static void ASTNode.{{logConsoleOut}}(String message, Throwable t) {
+    System.out.println(message);
+    t.printStackTrace();
+  }
+
+  static void ASTNode.{{logConsoleErr}}(String message, Object... args) {
+    System.err.println(String.format(message, args));
+  }
+
+  static void ASTNode.{{logConsoleErr}}(String message, Throwable t) {
+    System.err.println(message);
+    t.printStackTrace();
+  }
+
   public void {{rootNodeName}}.ragconnectCheckIncremental() {
   {{#configIncrementalOptionActive}}
     // check if --tracing is active
@@ -154,7 +172,8 @@ aspect RagConnectObserver {
     private void internal_add(RagConnectToken connectToken, ASTNode node, String attributeString,
         boolean compareParams, Object params, Runnable attributeCall) {
       {{#configLoggingEnabledForIncremental}}
-      System.out.println("** observer add: " + node + " on " + attributeString + (compareParams ? " (parameterized)" : ""));
+      {{logDebug}}("** observer add: {{log_}} on {{log_}}{{log_}}",
+        node, attributeString, (compareParams ? " (parameterized)" : ""));
       {{/configLoggingEnabledForIncremental}}
       // either add to an existing entry (with same node, attribute) or create new entry
       boolean needNewEntry = true;
@@ -193,7 +212,7 @@ aspect RagConnectObserver {
       // react to INC_FLUSH_START and remember entry
       if (event == ASTState.Trace.Event.INC_FLUSH_START) {
         {{#configLoggingEnabledForIncremental}}
-        System.out.println("** observer start: " + node + " on " + attribute);
+        {{logDebug}}("** observer start: {{log_}} on {{log_}}", node, attribute);
         {{/configLoggingEnabledForIncremental}}
         startEntries.addFirst(new RagConnectObserverStartEntry(node, attribute, value));
         return;
@@ -203,7 +222,7 @@ aspect RagConnectObserver {
       if (event == ASTState.Trace.Event.INC_FLUSH_END) {
         if (startEntries.isEmpty()) {
           {{#configLoggingEnabledForIncremental}}
-          System.out.println("** observer end without start! for " + node + " on " + attribute);
+          {{logDebug}}("** observer end without start! for {{log_}} on {{log_}}", node, attribute);
           {{/configLoggingEnabledForIncremental}}
           return;
         }
@@ -216,7 +235,8 @@ aspect RagConnectObserver {
           entryQueue.clear();
           startEntries.removeFirst();
           {{#configLoggingEnabledForIncremental}}
-          System.out.println("** observer process (entries: " + entriesToProcess.length + "): " + node + " on " + attribute);
+          {{logDebug}}("** observer process (entries: {{log_}}): {{log_}} on {{log_}}",
+            entriesToProcess.length, node, attribute);
           {{/configLoggingEnabledForIncremental}}
           for (RagConnectObserverEntry entry : entriesToProcess) {
             entry.attributeCall.run();
@@ -232,14 +252,14 @@ aspect RagConnectObserver {
       }
 
       {{#configLoggingEnabledForIncremental}}
-      System.out.println("** observer check INC_FLUSH_ATTR event: " + node + " on " + attribute);
+      {{logDebug}}("** observer check INC_FLUSH_ATTR event: {{log_}} on {{log_}}", node, attribute);
       {{/configLoggingEnabledForIncremental}}
       // iterate through list, if matching pair. could maybe be more efficient.
       for (RagConnectObserverEntry entry : observedNodes) {
         if (entry.node.equals(node) && entry.attributeString.equals(attribute) && (!entry.compareParams || java.util.Objects.equals(entry.params, params))) {
           // hit. call the attribute/nta-token
           {{#configLoggingEnabledForIncremental}}
-          System.out.println("** observer hit: " + entry.node + " on " + entry.attributeString);
+          {{logDebug}}("** observer hit: {{log_}} on {{log_}}", entry.node, entry.attributeString);
           {{/configLoggingEnabledForIncremental}}
 {{#configExperimentalJastAdd329}}
           entryQueue.add(entry);
diff --git a/ragconnect.base/src/main/resources/receiveDefinition.mustache b/ragconnect.base/src/main/resources/receiveDefinition.mustache
index 3bd20363ab557af22e937f7cbc35a869df3dc075..cb4dc8dc718eba53b0cd6a3bce9b4f996cdd4675 100644
--- a/ragconnect.base/src/main/resources/receiveDefinition.mustache
+++ b/ragconnect.base/src/main/resources/receiveDefinition.mustache
@@ -27,7 +27,7 @@ public boolean {{parentTypeName}}.{{connectMethodName}}(String {{connectParamete
   java.util.function.BiConsumer<String, byte[]> consumer = (topic, message) -> {
     {{> mappingApplication}}
 {{#configLoggingEnabledForReads}}
-    System.out.println("[Receive] " + {{connectParameterName}} + " -> {{entityName}} = " + {{lastResult}});
+    {{logDebug}}("[Receive] {{log_}} -> {{entityName}} = {{log_}}", {{connectParameterName}}, {{lastResult}});
 {{/configLoggingEnabledForReads}}
 {{#hasTypeEndpointTarget}}
     {{lastResult}}.treeResolveAll();
@@ -73,7 +73,8 @@ public boolean {{parentTypeName}}.{{connectMethodName}}(String {{connectParamete
     int index = {{resolveInListMethodName}}(topic);
     {{> mappingApplication}}
 {{#configLoggingEnabledForReads}}
-    System.out.println("[Receive] " + {{connectParameterName}} + " (" + topic + ") -> {{entityName}} = " + {{lastResult}});
+    {{logDebug}}("[Receive] {{log_}} ({{log_}}) -> {{entityName}} = {{log_}}",
+      {{connectParameterName}}, topic, {{lastResult}});
 {{/configLoggingEnabledForReads}}
     {{lastResult}}.set{{idTokenName}}(topic);
     if (index == -1) {
@@ -110,7 +111,7 @@ private boolean {{parentTypeName}}.{{internalConnectMethodName}}(String {{connec
   {{/InUse}}
   {{/restHandler}}
     default:
-      System.err.println("Unknown protocol '" + scheme + "'.");
+      {{logError}}("Unknown protocol '{{log_}}'.", scheme);
       success = false;
   }
   if (success) {
@@ -123,7 +124,8 @@ public boolean {{parentTypeName}}.{{disconnectMethodName}}(String {{connectParam
   {{>handleUri}}
   java.util.List<RagConnectToken> connectTokens = connectTokenMap.removeAll(this, true, uri, "{{entityName}}");
   if (connectTokens.isEmpty()) {
-    System.err.println("Disconnect called without connection for receiving " + this + ".{{entityName}} to '" + {{connectParameterName}} + "'!");
+    {{logWarn}}("Disconnect called without connection for receiving {{log_}}.{{entityName}} to '{{log_}}'!",
+      this, {{connectParameterName}});
     return false;
   }
   RagConnectDisconnectHandlerMethod disconnectingMethod;
@@ -141,7 +143,8 @@ public boolean {{parentTypeName}}.{{disconnectMethodName}}(String {{connectParam
   {{/InUse}}
   {{/restHandler}}
     default:
-      System.err.println("Unknown protocol '" + scheme + "' in '" + {{connectParameterName}} + "' for disconnecting {{parentTypeName}}.{{entityName}}");
+      {{logError}}("Unknown protocol '{{log_}}' in '{{log_}}' for disconnecting {{parentTypeName}}.{{entityName}}",
+        scheme, {{connectParameterName}});
       return false;
   }
   boolean success = true;
diff --git a/ragconnect.base/src/main/resources/sendDefinition.mustache b/ragconnect.base/src/main/resources/sendDefinition.mustache
index 18d48cafc978318d3e06b32af8e9f315e75c31a4..b066c690444a48cb8aadd64ccdd2dcdc2a46f78d 100644
--- a/ragconnect.base/src/main/resources/sendDefinition.mustache
+++ b/ragconnect.base/src/main/resources/sendDefinition.mustache
@@ -12,7 +12,7 @@ public boolean {{parentTypeName}}.{{connectMethodName}}(String {{connectParamete
       final String topic = {{attributeName}}().extractTopic(uri);
       {{senderName}}.add(() -> {
         {{#configLoggingEnabledForWrites}}
-        System.out.println("[Send] {{entityName}} = " + {{getterMethodCall}} + " -> " + {{connectParameterName}});
+        {{logDebug}}("[Send] {{entityName}} = {{log_}} -> {{log_}}", {{getterMethodCall}}, {{connectParameterName}});
         {{/configLoggingEnabledForWrites}}
         handler.publish(topic, {{lastValueGetterCall}});
         }{{#IndexBasedListAccess}}, index{{/IndexBasedListAccess}}, connectToken);
@@ -35,7 +35,7 @@ public boolean {{parentTypeName}}.{{connectMethodName}}(String {{connectParamete
   {{/InUse}}
   {{/restHandler}}
     default:
-      System.err.println("Unknown protocol '" + scheme + "'.");
+      {{logError}}("Unknown protocol '{{log_}}'.", scheme);
       success = false;
   }
   if (success) {
@@ -63,7 +63,8 @@ public boolean {{parentTypeName}}.{{disconnectMethodName}}(String {{connectParam
   {{>handleUri}}
   java.util.List<RagConnectToken> connectTokens = connectTokenMap.removeAll(this, false, uri, "{{entityName}}");
   if (connectTokens.isEmpty()) {
-    System.err.println("Disconnect called without connection for sending " + this + ".{{entityName}} to '" + {{connectParameterName}} + "'!");
+    {{logWarn}}("Disconnect called without connection for sending {{log_}}.{{entityName}} to '{{log_}}'!",
+      this, {{connectParameterName}});
     return false;
   }
   {{#configIncrementalOptionActive}}
@@ -86,7 +87,8 @@ public boolean {{parentTypeName}}.{{disconnectMethodName}}(String {{connectParam
   {{/InUse}}
   {{/restHandler}}
     default:
-      System.err.println("Unknown protocol '" + scheme + "' in '" + {{connectParameterName}} + "' for disconnecting {{parentTypeName}}.{{entityName}}");
+      {{logError}}("Unknown protocol '{{log_}}' in '{{log_}}' for disconnecting {{parentTypeName}}.{{entityName}}",
+        scheme, {{connectParameterName}});
       return false;
   }
   boolean success = true;
diff --git a/ragconnect.base/src/main/resources/typeDecl.mustache b/ragconnect.base/src/main/resources/typeDecl.mustache
index e37001ee779e6d5fcf471a80085a6a2817b7882b..1f674da36852786afab198b086b39b3cbf543b7b 100644
--- a/ragconnect.base/src/main/resources/typeDecl.mustache
+++ b/ragconnect.base/src/main/resources/typeDecl.mustache
@@ -27,7 +27,7 @@ public boolean {{Name}}.{{connectMethodName}}(String {{connectParameterName}}{{#
     {{/isListComponent}}
   {{/occurencesInProductionRules}}
     default:
-      System.err.println("No matching context while connecting " + this + " to " + {{connectParameterName}});
+      {{logError}}("No matching context while connecting {{log_}} to {{log_}}", this, {{connectParameterName}});
       return false;
   }
 }
@@ -38,7 +38,7 @@ public boolean {{Name}}.{{disconnectMethodName}}(String {{connectParameterName}}
   case "{{parentTypeName}}.{{Name}}": return (({{parentTypeName}}) _ragconnect_myParent()).{{disconnectMethodName}}({{connectParameterName}});
 {{/occurencesInProductionRules}}
     default:
-      System.err.println("No matching context while disconnecting for " + this + " from " + {{connectParameterName}});
+      {{logError}}("No matching context while disconnecting {{log_}} to {{log_}}", this, {{connectParameterName}});
       return false;
   }
 }
diff --git a/ragconnect.tests/build.gradle b/ragconnect.tests/build.gradle
index 8bc120a2d071c77105a2560ac5b8a8b204883d1d..468c22acdfb055d1820c30158049248e4e0b98be 100644
--- a/ragconnect.tests/build.gradle
+++ b/ragconnect.tests/build.gradle
@@ -9,7 +9,7 @@ buildscript {
     }
     dependencies {
         classpath 'org.jastadd:jastaddgradle:1.13.3'
-        classpath 'org.jastadd.preprocessor:testing:0.2.11'
+        classpath 'org.jastadd.preprocessor:testing:0.2.12'
     }
 }
 
@@ -60,7 +60,7 @@ dependencies {
 
     // rest and client
     testImplementation group: 'com.sparkjava', name: 'spark-core', version: '2.9.3'
-    testImplementation group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.11.2'
+    testImplementation group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.17.1'
     testImplementation group: 'org.glassfish.jersey.core', name: 'jersey-client', version: '2.31'
     testImplementation group: 'org.glassfish.jersey.inject', name: 'jersey-hk2', version: '2.31'
     testImplementation group: 'javax.activation', name: 'activation', version: '1.1.1'
@@ -158,6 +158,7 @@ task compileExampleTest(type: RagConnectTest) {
         inputFiles = [file('src/test/01-input/example/Test.relast'),
                       file('src/test/01-input/example/Test.connect')]
         rootNode = 'Model'
+        extraOptions = defaultRagConnectOptionsAnd()
     }
     relast {
         useJastAddNames = true
@@ -177,6 +178,7 @@ task compileDefaultOnlyRead(type: RagConnectTest) {
         inputFiles = [file('src/test/01-input/defaultOnlyRead/Test.relast'),
                       file('src/test/01-input/defaultOnlyRead/Test.connect')]
         rootNode = 'A'
+        extraOptions = defaultRagConnectOptionsAnd()
     }
     relast {
         useJastAddNames = true
@@ -195,6 +197,7 @@ task compileDefaultOnlyWrite(type: RagConnectTest) {
         inputFiles = [file('src/test/01-input/defaultOnlyWrite/Test.relast'),
                       file('src/test/01-input/defaultOnlyWrite/Test.connect')]
         rootNode = 'A'
+        extraOptions = defaultRagConnectOptionsAnd()
     }
     relast {
         useJastAddNames = true
@@ -214,6 +217,7 @@ task compileRead1write2(type: RagConnectTest) {
         inputFiles = [file('src/test/01-input/read1write2/Test.relast'),
                       file('src/test/01-input/read1write2/Test.connect')]
         rootNode = 'A'
+        extraOptions = defaultRagConnectOptionsAnd()
     }
     relast {
         useJastAddNames = true
@@ -233,6 +237,7 @@ task compileRead2write1(type: RagConnectTest) {
         inputFiles = [file('src/test/01-input/read2write1/Test.relast'),
                       file('src/test/01-input/read2write1/Test.connect')]
         rootNode = 'A'
+        extraOptions = defaultRagConnectOptionsAnd()
     }
     relast {
         useJastAddNames = true
@@ -253,6 +258,7 @@ task compileVia(type: RagConnectTest) {
                       file('src/test/01-input/via/Test.connect')]
         rootNode = 'A'
         protocols = ['mqtt', 'rest']
+        extraOptions = defaultRagConnectOptionsAnd()
     }
     relast {
         useJastAddNames = true
@@ -272,6 +278,7 @@ task compileTokenValueSend(type: RagConnectTest) {
         inputFiles = [file('src/test/01-input/tokenValueSend/Test.relast'),
                       file('src/test/01-input/tokenValueSend/Test.connect')]
         rootNode = 'A'
+        extraOptions = defaultRagConnectOptionsAnd()
     }
     relast {
         useJastAddNames = true
@@ -291,6 +298,7 @@ task compileTutorial(type: RagConnectTest) {
         inputFiles = [file('src/test/01-input/tutorial/Test.relast'),
                       file('src/test/01-input/tutorial/Test.connect')]
         rootNode = 'A'
+        extraOptions = defaultRagConnectOptionsAnd()
     }
     relast {
         useJastAddNames = true
@@ -310,6 +318,7 @@ task compileIncremental(type: RagConnectTest) {
         inputFiles = [file('src/test/01-input/incremental/Test.relast'),
                       file('src/test/01-input/incremental/Test.connect')]
         rootNode = 'A'
+        extraOptions = defaultRagConnectOptionsAnd()
     }
     relast {
         useJastAddNames = true
@@ -330,6 +339,7 @@ task compileMapping(type: RagConnectTest) {
         inputFiles = [file('src/test/01-input/mapping/Test.relast'),
                       file('src/test/01-input/mapping/Test.connect')]
         rootNode = 'A'
+        extraOptions = defaultRagConnectOptionsAnd()
     }
     relast {
         useJastAddNames = true
@@ -350,6 +360,7 @@ task compileTreeManual(type: RagConnectTest, dependsOn: ':ragconnect.base:compil
                       file('src/test/01-input/tree/Test.connect'),
                       file('src/test/01-input/tree/TestDependencies.connect')]
         rootNode = 'Root'
+        extraOptions = defaultRagConnectOptionsAnd()
     }
     relast {
         useJastAddNames = true
@@ -370,6 +381,7 @@ task compileTreeIncremental(type: RagConnectTest) {
         inputFiles = [file('src/test/01-input/tree/Test.relast'),
                       file('src/test/01-input/tree/Test.connect')]
         rootNode = 'Root'
+        extraOptions = defaultRagConnectOptionsAnd()
     }
     relast {
         useJastAddNames = true
@@ -392,6 +404,7 @@ task compileTreeAllowedTokens(type: RagConnectTest) {
                       file('src/test/01-input/treeAllowedTokens/Test.connect'),
                       file('src/test/01-input/treeAllowedTokens/TestDependencies.connect')]
         rootNode = 'Root'
+        extraOptions = defaultRagConnectOptionsAnd()
     }
     relast {
         useJastAddNames = true
@@ -412,6 +425,7 @@ task compileTreeAllowedTokensIncremental(type: RagConnectTest) {
         inputFiles = [file('src/test/01-input/treeAllowedTokens/Test.relast'),
                       file('src/test/01-input/treeAllowedTokens/Test.connect')]
         rootNode = 'Root'
+        extraOptions = defaultRagConnectOptionsAnd()
     }
     relast {
         useJastAddNames = true
@@ -427,13 +441,14 @@ task compileTreeAllowedTokensIncremental(type: RagConnectTest) {
 }
 
 // --- Test: list-manual ---
-task compileListManual(type: RagConnectTest, dependsOn: ':ragconnect.base:jar') {
+task compileListManual(type: RagConnectTest) {
     ragconnect {
         outputDir = file('src/test/02-after-ragconnect/list')
         inputFiles = [file('src/test/01-input/list/Test.relast'),
                       file('src/test/01-input/list/Test.connect'),
                       file('src/test/01-input/list/TestDependencies.connect')]
         rootNode = 'Root'
+        extraOptions = defaultRagConnectOptionsAnd()
     }
     relast {
         useJastAddNames = true
@@ -448,12 +463,13 @@ task compileListManual(type: RagConnectTest, dependsOn: ':ragconnect.base:jar')
 }
 
 // --- Test: list-incremental ---
-task compileListIncremental(type: RagConnectTest, dependsOn: ':ragconnect.base:jar') {
+task compileListIncremental(type: RagConnectTest) {
     ragconnect {
         outputDir = file('src/test/02-after-ragconnect/listInc')
         inputFiles = [file('src/test/01-input/list/Test.relast'),
                       file('src/test/01-input/list/Test.connect')]
         rootNode = 'Root'
+        extraOptions = defaultRagConnectOptionsAnd()
     }
     relast {
         useJastAddNames = true
@@ -469,13 +485,14 @@ task compileListIncremental(type: RagConnectTest, dependsOn: ':ragconnect.base:j
 }
 
 // --- Test: singleList-manual ---
-task compileSingleListManual(type: RagConnectTest, dependsOn: ':ragconnect.base:jar') {
+task compileSingleListManual(type: RagConnectTest) {
     ragconnect {
         outputDir = file('src/test/02-after-ragconnect/singleList')
         inputFiles = [file('src/test/01-input/singleList/Test.relast'),
                       file('src/test/01-input/singleList/Test.connect'),
                       file('src/test/01-input/singleList/TestDependencies.connect')]
         rootNode = 'Root'
+        extraOptions = defaultRagConnectOptionsAnd()
     }
     relast {
         useJastAddNames = true
@@ -490,12 +507,13 @@ task compileSingleListManual(type: RagConnectTest, dependsOn: ':ragconnect.base:
 }
 
 // --- Test: singleList-incremental ---
-task compileSingleListIncremental(type: RagConnectTest, dependsOn: ':ragconnect.base:jar') {
+task compileSingleListIncremental(type: RagConnectTest) {
     ragconnect {
         outputDir = file('src/test/02-after-ragconnect/singleListInc')
         inputFiles = [file('src/test/01-input/singleList/Test.relast'),
                       file('src/test/01-input/singleList/Test.connect')]
         rootNode = 'Root'
+        extraOptions = defaultRagConnectOptionsAnd()
     }
     relast {
         useJastAddNames = true
@@ -511,13 +529,14 @@ task compileSingleListIncremental(type: RagConnectTest, dependsOn: ':ragconnect.
 }
 
 // --- Test: singleListVariant-manual ---
-task compileSingleListVariantManual(type: RagConnectTest, dependsOn: ':ragconnect.base:jar') {
+task compileSingleListVariantManual(type: RagConnectTest) {
     ragconnect {
         outputDir = file('src/test/02-after-ragconnect/singleListVariant')
         inputFiles = [file('src/test/01-input/singleListVariant/Test.relast'),
                       file('src/test/01-input/singleListVariant/Test.connect'),
                       file('src/test/01-input/singleListVariant/TestDependencies.connect')]
         rootNode = 'Root'
+        extraOptions = defaultRagConnectOptionsAnd()
     }
     relast {
         useJastAddNames = true
@@ -532,13 +551,13 @@ task compileSingleListVariantManual(type: RagConnectTest, dependsOn: ':ragconnec
 }
 
 // --- Test: singleListVariant-incremental ---
-task compileSingleListVariantIncremental(type: RagConnectTest, dependsOn: ':ragconnect.base:jar') {
+task compileSingleListVariantIncremental(type: RagConnectTest) {
     ragconnect {
         outputDir = file('src/test/02-after-ragconnect/singleListVariantInc')
         inputFiles = [file('src/test/01-input/singleListVariant/Test.relast'),
                       file('src/test/01-input/singleListVariant/Test.connect')]
         rootNode = 'Root'
-        extraOptions = ['--experimental-jastadd-329']
+        extraOptions = defaultRagConnectOptionsAnd(['--experimental-jastadd-329'])
     }
     relast {
         useJastAddNames = true
@@ -554,13 +573,13 @@ task compileSingleListVariantIncremental(type: RagConnectTest, dependsOn: ':ragc
 }
 
 // --- Test: contextFreeSimple-incremental ---
-task compileContextFreeSimpleIncremental(type: RagConnectTest, dependsOn: ':ragconnect.base:jar') {
+task compileContextFreeSimpleIncremental(type: RagConnectTest) {
     ragconnect {
         outputDir = file('src/test/02-after-ragconnect/contextFreeSimpleInc')
         inputFiles = [file('src/test/01-input/contextFreeSimple/Test.relast'),
                       file('src/test/01-input/contextFreeSimple/Test.connect')]
         rootNode = 'Root'
-        extraOptions = ['--experimental-jastadd-329']
+        extraOptions = defaultRagConnectOptionsAnd(['--experimental-jastadd-329'])
     }
     relast {
         useJastAddNames = true
@@ -575,13 +594,13 @@ task compileContextFreeSimpleIncremental(type: RagConnectTest, dependsOn: ':ragc
 }
 
 // --- Test: forwarding-incremental ---
-task compileForwardingIncremental(type: RagConnectTest, dependsOn: ':ragconnect.base:jar') {
+task compileForwardingIncremental(type: RagConnectTest) {
     ragconnect {
         outputDir = file('src/test/02-after-ragconnect/forwardingInc')
         inputFiles = [file('src/test/01-input/forwarding/Test.relast'),
                       file('src/test/01-input/forwarding/Test.connect')]
         rootNode = 'Root'
-        extraOptions = ['--experimental-jastadd-329']
+        extraOptions = defaultRagConnectOptionsAnd(['--experimental-jastadd-329'])
     }
     relast {
         useJastAddNames = true
@@ -596,13 +615,13 @@ task compileForwardingIncremental(type: RagConnectTest, dependsOn: ':ragconnect.
 }
 
 // --- Test: indexed-send-incremental ---
-task compileIndexedSendIncremental(type: RagConnectTest, dependsOn: ':ragconnect.base:jar') {
+task compileIndexedSendIncremental(type: RagConnectTest) {
     ragconnect {
         outputDir = file('src/test/02-after-ragconnect/indexedSendInc')
         inputFiles = [file('src/test/01-input/indexedSend/Test.relast'),
                       file('src/test/01-input/indexedSend/Test.connect')]
         rootNode = 'Root'
-        extraOptions = ['--experimental-jastadd-329']
+        extraOptions = defaultRagConnectOptionsAnd(['--experimental-jastadd-329'])
     }
     relast {
         useJastAddNames = true
@@ -618,13 +637,13 @@ task compileIndexedSendIncremental(type: RagConnectTest, dependsOn: ':ragconnect
 }
 
 // --- Test: attribute-incremental ---
-task compileAttributeIncremental(type: RagConnectTest, dependsOn: ':ragconnect.base:jar') {
+task compileAttributeIncremental(type: RagConnectTest) {
     ragconnect {
         outputDir = file('src/test/02-after-ragconnect/attributeInc')
         inputFiles = [file('src/test/01-input/attribute/Test.relast'),
                       file('src/test/01-input/attribute/Test.connect')]
         rootNode = 'Root'
-        extraOptions = ['--experimental-jastadd-329']
+        extraOptions = defaultRagConnectOptionsAnd(['--experimental-jastadd-329'])
     }
     relast {
         useJastAddNames = true
@@ -638,3 +657,11 @@ task compileAttributeIncremental(type: RagConnectTest, dependsOn: ':ragconnect.b
         extraOptions = JASTADD_INCREMENTAL_OPTIONS_TRACING_FULL
     }
 }
+compileAttributeIncremental.outputs.upToDateWhen { false }
+
+static ArrayList<String> defaultRagConnectOptionsAnd(ArrayList<String> options = []) {
+    if (!options.contains('--logTarget=slf4j')) {
+        options.add('--logTarget=slf4j')
+    }
+    return options
+}
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/AbstractMqttTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/AbstractMqttTest.java
index 648e6d300b06b72721efd2d75ba5134723aaee16..c537a1db389f34545e59fc9c45f3525ce421dd75 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/AbstractMqttTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/AbstractMqttTest.java
@@ -1,9 +1,9 @@
 package org.jastadd.ragconnect.tests;
 
 import defaultOnlyRead.ast.MqttHandler;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
 import org.junit.jupiter.api.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
@@ -20,7 +20,7 @@ public abstract class AbstractMqttTest {
 
   protected static MqttHandler publisher;
 
-  protected Logger logger = LogManager.getLogger(getClass());
+  protected Logger logger = LoggerFactory.getLogger(getClass());
 
   /**
    * if the initial/current value shall be sent upon connecting
@@ -65,7 +65,7 @@ public abstract class AbstractMqttTest {
     createModel();
     setupReceiverAndConnect();
 
-    logger.debug("Calling communicateSendInitialValue");
+    logger.info("Calling communicateSendInitialValue");
     communicateSendInitialValue();
   }
 
@@ -84,7 +84,7 @@ public abstract class AbstractMqttTest {
     createModel();
     setupReceiverAndConnect();
 
-    logger.debug("Calling communicateOnlyUpdatedValue");
+    logger.info("Calling communicateOnlyUpdatedValue");
     communicateOnlyUpdatedValue();
   }
 
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Errors.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Errors.java
index 4d32adff23abd12f2052f320466b79dc0f8673f5..63ee6de3ef515e46768a9dc9bfc75477a451bfd5 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Errors.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Errors.java
@@ -1,10 +1,10 @@
 package org.jastadd.ragconnect.tests;
 
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.io.File;
 import java.io.IOException;
@@ -22,7 +22,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 
 public class Errors {
 
-  private static final Logger logger = LogManager.getLogger(Errors.class);
+  private static final Logger logger = LoggerFactory.getLogger(Errors.class);
   private static final String FILENAME_PATTERN = "$FILENAME";
   private static final String ERROR_DIRECTORY = "errors/";
   private static final String OUTPUT_DIRECTORY = TestUtils.OUTPUT_DIRECTORY_PREFIX + ERROR_DIRECTORY;
@@ -53,10 +53,10 @@ public class Errors {
         .collect(Collectors.toList());
     Path outPath = TestUtils.runCompiler(grammarFile, connectFiles, rootNode, ERROR_DIRECTORY, 1);
 
-    final String startOfErrorsPattern = "SEVERE: Errors:";
+    final String startOfErrorsPattern = "Errors:\n";
     String out = readFile(outPath, Charset.defaultCharset());
     assertThat(out).contains(startOfErrorsPattern);
-    out = out.substring(out.indexOf(startOfErrorsPattern) + 16);
+    out = out.substring(out.indexOf(startOfErrorsPattern) + startOfErrorsPattern.length());
 
     Path expectedPath = Paths.get(TestUtils.INPUT_DIRECTORY_PREFIX)
         .resolve(ERROR_DIRECTORY)
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java
index 9a6c22bd962940b5d0dc0e942dcc91a3ca1fbf19..a3394ea07518bd5ca668fee774c7702ef5334c35 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java
@@ -3,12 +3,12 @@ package org.jastadd.ragconnect.tests;
 import com.fasterxml.jackson.core.JsonEncoding;
 import com.fasterxml.jackson.core.JsonFactory;
 import com.fasterxml.jackson.core.JsonGenerator;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
 import org.awaitility.Awaitility;
 import org.awaitility.core.ConditionFactory;
 import org.jastadd.ragconnect.compiler.Compiler;
 import org.junit.jupiter.api.Assertions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -36,7 +36,7 @@ import static org.junit.jupiter.api.Assertions.fail;
  */
 public class TestUtils {
 
-  private static final Logger logger = LogManager.getLogger(TestUtils.class);
+  private static final Logger logger = LoggerFactory.getLogger(TestUtils.class);
   public static final double DELTA = 0.001d;
   public static final String INPUT_DIRECTORY_PREFIX = "./src/test/01-input/";
   public static final String OUTPUT_DIRECTORY_PREFIX = "./src/test/02-after-ragconnect/";