[java-idp-plugin-jetty] 173/186: JJETTY-13 Implement Jetty-base plugin V2

Rod Widdowson rdw at steadingsoftware.com
Thu Jul 24 15:58:44 UTC 2025


This is an automated email from the git hooks/post-receive script.

rdw pushed a commit to branch dev/foo
in repository java-idp-plugin-jetty.

View the commit online:
http://git.shibboleth.net/view/?p=java-idp-plugin-jetty.git;a=commit;h=7a2f0efa99280f79cc8c4d94d3817b0f86356292

commit 7a2f0efa99280f79cc8c4d94d3817b0f86356292
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Thu Jul 10 16:42:37 2025 +0100

    JJETTY-13 Implement Jetty-base plugin V2
    
    https://shibboleth.atlassian.net/browse/JJETTY-13
    
    Start to put together the command line tools to download jetty and procmon.
    Skeleton and unit test only at this stage
---
 jetty-cli/pom.xml                                  |  96 +++++++++
 .../jetty/cli/impl/JettyDownloadArguments.java     | 186 +++++++++++++++++
 .../plugin/jetty/cli/impl/JettyDownloadCLI.java    | 231 +++++++++++++++++++++
 .../idp/plugin/jetty/cli/impl/package-info.java    |  20 ++
 .../jetty/cli/impl/JettyDownloadCLITest.java       |  79 +++++++
 .../resources/idphome-test/conf/idp.properties     |   2 +
 .../idphome-test/credentials/jetty-keystore.gpg    |   0
 jetty-cli/src/test/resources/logback-test.xml      |  20 ++
 pom.xml                                            |   1 +
 9 files changed, 635 insertions(+)

diff --git a/jetty-cli/pom.xml b/jetty-cli/pom.xml
new file mode 100644
index 0000000..8fd4ccc
--- /dev/null
+++ b/jetty-cli/pom.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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>net.shibboleth.idp.plugin.jetty</groupId>
+        <artifactId>jetty-plugin-parent</artifactId>
+        <version>0.9.0-SNAPSHOT</version>
+    </parent>
+
+    <name>Jettty: Command line code </name>
+    <description>
+        Project with the code for the Jetty plugin's "download" command.
+    </description>
+    <artifactId>jetty-plugin-cli</artifactId>
+    <packaging>jar</packaging>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>${idp.groupId}</groupId>
+            <artifactId>idp-cli</artifactId>
+            <version>${idp.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>${idp.groupId}</groupId>
+            <artifactId>idp-core</artifactId>
+            <version>${idp.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>${idp.groupId}</groupId>
+            <artifactId>idp-installer</artifactId>
+            <version>${idp.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>${shib-shared.groupId}</groupId>
+            <artifactId>shib-cli</artifactId>
+           <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>${slf4j.groupId}</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <scope>test</scope>
+        </dependency>
+        
+		<dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        
+		<dependency>
+            <groupId>org.apache.ant</groupId>
+            <artifactId>ant</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifestSections>
+                            <manifestSection>
+                                <name>net/shibboleth/idp/jettybase/plugin</name>
+                                <manifestEntries>
+                                    <Implementation-Title>${project.artifactId}</Implementation-Title>
+                                    <Implementation-Version>${project.version}</Implementation-Version>
+                                    <Implementation-Vendor>shibboleth.net</Implementation-Vendor>
+                                </manifestEntries>
+                            </manifestSection>
+                        </manifestSections>
+                    </archive>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/jetty-cli/src/main/java/net/shibboleth/idp/plugin/jetty/cli/impl/JettyDownloadArguments.java b/jetty-cli/src/main/java/net/shibboleth/idp/plugin/jetty/cli/impl/JettyDownloadArguments.java
new file mode 100644
index 0000000..955a931
--- /dev/null
+++ b/jetty-cli/src/main/java/net/shibboleth/idp/plugin/jetty/cli/impl/JettyDownloadArguments.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed 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 net.shibboleth.idp.plugin.jetty.cli.impl;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import com.beust.jcommander.Parameter;
+
+import net.shibboleth.idp.cli.AbstractIdPHomeAwareCommandLineArguments;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Command line arguments for the "Download" verb.
+ */
+public class JettyDownloadArguments extends AbstractIdPHomeAwareCommandLineArguments {
+    
+    /** Logger. */
+    @Nullable private Logger log;
+
+    /** The artifactId. */
+    @Parameter(names= {"--artifactId"})
+    @Nonnull private String artifactId = "jetty-home";
+
+    /** The groupId. */
+    @Parameter(names= {"--groupId"})
+    @Nonnull  private String groupId = "org.eclipse.jetty";
+    
+    /** The version. */
+    @Parameter(names= {"-v", "--downloadVersion"})
+    @Nullable private String version;
+    
+    /** The type. */
+    @Parameter(names= {"--type"})
+    @Nonnull  private String type = "tar.gz";
+
+    /** The classifier. */
+    @Parameter(names= {"--classifier"})
+    @Nonnull private String classifier="";
+    
+    /** Base of the repo. */
+    @Parameter(names= {"--mavenbase"})
+    @Nonnull private String mavenbase="https://repo1.maven.org/maven2";
+
+    /** keystore Location. */
+    @Parameter(names= {"--keystore"})
+    @Nonnull private String keystore="credentials/jetty-base-download-keystore.gpg";
+    
+    /** The FQP of the download base artifact.
+     * If not set, the command line initializes this from the maven coordinates. */
+    @Parameter(names= {"-fqp"})
+    @Nonnull private String fqp;
+    
+    /** Whether to download the signature file. */
+    @Parameter(names= {"--noascfile"})
+    @Nonnull private boolean noAscFile;
+    
+    /** Whether to do a signature check. */
+    @Parameter(names= {"--nosigcheck"})
+    @Nonnull private boolean noSigCheck;
+    
+    /** Whether to unpack. */
+    @Parameter(names= {"--nounpack"})
+    @Nonnull private boolean noUnpack;
+
+
+	/** {@inheritDoc} */
+	@Override
+	public Logger getLog() {
+        if (log == null) {
+            log = LoggerFactory.getLogger(JettyDownloadArguments.class);
+        }
+        assert log != null;
+        return log;
+	}
+
+    /**
+     * Get the group ID (maven coordinate).
+     * @return the groupId
+     */
+    @Nonnull public String getGroupId() {
+        return groupId;
+    }
+
+    /**
+     * Get the artifact ID (maven coordinate).
+	 * @return the artifactId
+	 */
+	@Nonnull public String getArtifactId() {
+        return artifactId;
+    }
+
+	/**
+	 * Get the classifier (maven coordinate).
+     * @return the classifier
+     */
+    @Nonnull public String getClassifier() {
+        return classifier;
+    }
+
+    /**
+     * Get the type (maven coordinate).
+     * @return the type
+     */
+    @Nonnull public String getType() {
+        return type;
+    }
+    
+    /**
+     * Get the version (maven coordinate).
+     * @return the version
+     */
+	@Nullable public String getVersion() {
+        return version;
+    }
+	
+	/**
+	 * Get the URL that anchors the maven repository.
+	 * @return the base of the URL.
+	 */
+	@Nonnull public String getMavenbase() {
+        return mavenbase;
+    }
+	
+	/**
+	 * Are we downloading the asc file?
+	 * @return what to do
+	 */
+	public boolean isNoAscFile() {
+        return noAscFile;
+    }
+	
+	/**
+	 * Have we suppressed signature checking - either explicitly or
+	 *  by saying "no asc file".
+	 * @return what to do
+	 */
+	public boolean isNoSigCheck() {
+        return noAscFile || noSigCheck;
+    }
+	
+	/**
+	 * Are we just downloading?
+	 * @return what to do
+	 */
+	public boolean isNoUnpack() {
+        return noUnpack;
+    }
+	
+	/**
+	 * Set the fully qualified path we are to download path.
+	 * @param what the path
+	 */
+	public void setFqp(@Nonnull String what) {
+        fqp = Constraint.isNotNull(what, "injected FPQ must be non null");
+    }
+
+    /**
+     * What is the fully qualified path we are to download path?
+	 * @return the path
+	 */
+	@Nullable public String getFqp() {
+        return fqp;
+    }
+	
+	/** get keystore location (relative to idp home).
+	 * @return the location
+	 */
+	public String getKeystore() {
+        return keystore;
+    }
+}
diff --git a/jetty-cli/src/main/java/net/shibboleth/idp/plugin/jetty/cli/impl/JettyDownloadCLI.java b/jetty-cli/src/main/java/net/shibboleth/idp/plugin/jetty/cli/impl/JettyDownloadCLI.java
new file mode 100644
index 0000000..e23ea6b
--- /dev/null
+++ b/jetty-cli/src/main/java/net/shibboleth/idp/plugin/jetty/cli/impl/JettyDownloadCLI.java
@@ -0,0 +1,231 @@
+/*
+ * Licensed 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 net.shibboleth.idp.plugin.jetty.cli.impl;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import net.shibboleth.idp.Version;
+import net.shibboleth.idp.cli.AbstractIdPHomeAwareCommandLine;
+import net.shibboleth.shared.cli.AbstractCommandLine;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+public class JettyDownloadCLI extends AbstractIdPHomeAwareCommandLine<JettyDownloadArguments> {
+
+    /** Logger. */
+    @Nullable private Logger log;
+    
+    /** the keystore (if provided). */
+    @Nullable private Path keyStore;
+    
+    /** Where we are downloading to. */
+    private Path downloadsDir;
+    
+    /** The name we will download to (including type). */
+    private String downloadFileName;
+
+    /** The directory we will unpack to (including type). */
+    private String downloadDirName;
+
+	/** {@inheritDoc} */
+	@Override
+	protected Class<JettyDownloadArguments> getArgumentClass() {
+		return JettyDownloadArguments.class;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	protected String getVersion() {
+        final String result = Version.getVersion();
+        assert result != null;
+        return result;	}
+
+	/** {@inheritDoc} */
+	@Override
+	protected Logger getLogger() {
+        Logger localLog = log;
+        if (localLog == null) {
+            localLog = log = LoggerFactory.getLogger(JettyDownloadCLI.class);
+        }
+        return localLog;
+	}
+	
+	/** if no name was specified then plug the maven coordinates together
+	 * @param args
+	 */
+	@Nonnull private String deriveNameFromCoordinates(@Nonnull final JettyDownloadArguments args) {
+        //
+        // Root of request 
+        //   https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-home/12.0.23/jetty-home-12.0.23
+        //   https://repo1.maven.org/maven2/commons-daemon/commons-daemon/1.4.1/commons-daemon-1.4.1
+        //
+        final StringBuilder sb = new StringBuilder(args.getMavenbase())
+                .append('/')
+                .append(args.getGroupId().replaceAll("\\.", "/"))
+                .append('/')
+                .append(args.getArtifactId())
+                .append('/')
+                .append(args.getVersion())
+                .append('/')
+                .append(args.getArtifactId())
+                .append('-')
+                .append(args.getVersion());
+        
+        final String classifier = args.getClassifier();
+        if (classifier != null) {
+            //
+            // Add classifier
+            //    https://repo1.maven.org/maven2/commons-daemon/commons-daemon/1.4.1/commons-daemon-1.4.1-bin-windows
+            //
+            sb.append(args.getClassifier());
+        }
+        //
+        // Add type
+        //   https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-home/12.0.23/jetty-home-12.0.23.tar.gz
+        //   https://repo1.maven.org/maven2/commons-daemon/commons-daemon/1.4.1/commons-daemon-1.4.1-bin-windows.zip
+        //
+        sb.append('.').append(args.getType());
+        return sb.toString();
+	}
+
+	@Override
+	protected int doRun(@Nonnull final JettyDownloadArguments args) {
+	    
+	    super.doRun(args);
+	    
+	    if (args.getFqp() == null) {
+	        //
+	        // Calculate the address
+	        //
+	        if (args.getVersion() == null) {
+	            getLogger().error("No version and no FQP supplied");
+	            return RC_IO;
+	        }
+	        args.setFqp(deriveNameFromCoordinates(args));
+	    }
+	    
+	    downloadDirName = args.getArtifactId();
+        if (args.getVersion() != null) {
+            downloadDirName += "-" + args.getVersion();
+	    }
+        downloadFileName = downloadDirName + "." + args.getType();
+        
+        final String pathString = Constraint.isNotNull(
+                getApplicationContext().getEnvironment().getProperty("idp.home"), "idp home must be specified");
+        final Path idpHome;
+        try {
+            idpHome = Path.of(pathString);
+        } catch (final Exception ex) {
+            getLogger().error("Could not find idp home at {}", pathString, ex);
+            return RC_IO;            
+        }
+	    
+	    if (!args.isNoSigCheck()) {
+	        
+	        keyStore = idpHome.resolve(args.getKeystore());
+	        
+	        if (Files.exists(keyStore)) {
+                getLogger().error("keystore file {} does not exist", keyStore);
+                return RC_IO;
+	        }
+	    }
+	    downloadsDir = idpHome.resolve("jetty-downloads");
+
+	    if (Files.exists(downloadsDir)) {
+	        if (!Files.isDirectory(downloadsDir)) {
+	            getLogger().error("{} is not a directory", downloadsDir);
+	        }
+	    } else {
+	        try {
+	            Files.createDirectory(downloadsDir);                
+            } catch (final IOException e) {
+                getLogger().error("Could not create {}", downloadsDir, e);
+                return RC_IO;                
+            }
+	    }
+	    
+	    int result = download(args);
+	    if (result != RC_OK) {
+	        return result;
+	    }
+	    result = sigCheck(args);
+        if (result != RC_OK) {
+            return result;
+        }
+	    result = unpack(args);
+        if (result != RC_OK) {
+            return result;
+        }
+        return RC_OK;
+	}
+
+    /** Download the files from the remote server.
+     * @param args the {@link JettyDownloadArguments} we were given.
+     * @return an RC result
+     */
+    private int download(JettyDownloadArguments args) {
+        getLogger().info("Would download {} to {}", args.getFqp(), downloadFileName);
+        if (!args.isNoAscFile()) {
+            getLogger().info("Would download {}.asc to {}.asc", args.getFqp(), downloadFileName);            
+        }
+        return RC_OK;
+    }
+
+    
+    /** Check the signature on the downloaded files.
+     * @param args the {@link JettyDownloadArguments} we were given.
+     * @return an RC result
+     */
+    private int sigCheck(JettyDownloadArguments args) {
+        return RC_OK;
+    }
+
+    /** Unpack the downloaded file.
+     * @param args the {@link JettyDownloadArguments} we were given.
+     * @return an RC result
+     */
+    private int unpack(JettyDownloadArguments args) {
+        return RC_OK;
+    }
+    
+    /** Shim for CLI entry point: Allows the code to be run from a test.
+    *
+    * @return one of the predefines {@link AbstractCommandLine#RC_INIT},
+    * {@link AbstractCommandLine#RC_IO}, {@link AbstractCommandLine#RC_OK}
+    * or {@link AbstractCommandLine#RC_UNKNOWN}
+    *
+    * @param args arguments
+    */
+   public static int runMain(@Nonnull final String[] args) {
+       final JettyDownloadCLI cli = new JettyDownloadCLI();
+
+       return cli.run(args);
+   }
+   
+   /**
+    * CLI entry point.
+    * @param args arguments
+    */
+   public static void main(@Nonnull final String[] args) {
+       System.exit(runMain(args));
+   }
+
+}
diff --git a/jetty-cli/src/main/java/net/shibboleth/idp/plugin/jetty/cli/impl/package-info.java b/jetty-cli/src/main/java/net/shibboleth/idp/plugin/jetty/cli/impl/package-info.java
new file mode 100644
index 0000000..3a11c4c
--- /dev/null
+++ b/jetty-cli/src/main/java/net/shibboleth/idp/plugin/jetty/cli/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Licensed 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.
+ */
+/**
+ * Implementation classes for Command line tools.
+ */
+ at NonnullElements
+package net.shibboleth.idp.plugin.jetty.cli.impl;
+
+import net.shibboleth.shared.annotation.constraint.NonnullElements;
diff --git a/jetty-cli/src/test/java/net/shibboleth/idp/plugin/jetty/cli/impl/JettyDownloadCLITest.java b/jetty-cli/src/test/java/net/shibboleth/idp/plugin/jetty/cli/impl/JettyDownloadCLITest.java
new file mode 100644
index 0000000..febb52d
--- /dev/null
+++ b/jetty-cli/src/test/java/net/shibboleth/idp/plugin/jetty/cli/impl/JettyDownloadCLITest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed 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 net.shibboleth.idp.plugin.jetty.cli.impl;
+
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+
+import javax.annotation.Nonnull;
+
+import org.slf4j.Logger;
+import org.springframework.core.io.ClassPathResource;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.Test;
+
+import net.shibboleth.idp.installer.InstallerSupport;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+public class JettyDownloadCLITest {
+
+    private static Path idpHome;
+    
+    @Nonnull private final Logger log = LoggerFactory.getLogger(JettyDownloadCLITest.class);
+
+    @BeforeSuite public void setupIdpHome() throws IOException {
+        idpHome = Files.createTempDirectory("JettyCLITests");
+        System.setProperty("idp.home",idpHome.toString());
+        Path from = new ClassPathResource("idphome-test").getFile().toPath();
+        Files.walkFileTree(from, new SimpleFileVisitor<Path>() {
+            @Override
+            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
+                Path rel = from.relativize(dir);
+                Path to = idpHome.resolve(rel);
+                if (!Files.exists(to)) {
+                    log.trace("Creating directory {}", to);
+                    Files.createDirectory(to);
+                }
+                return FileVisitResult.CONTINUE;
+            };
+            @Override
+            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+                Path rel = from.relativize(file);
+                Path to = idpHome.resolve(rel);
+                log.trace("Copying from {} to {}", file, to);
+                Files.copy(file,  to);
+                return FileVisitResult.CONTINUE;
+            }
+        });
+    }
+
+    @AfterSuite public void teardownIdPHome() throws IOException {
+        final Path ih = idpHome;
+        if (ih == null) {
+            return;
+        }
+        InstallerSupport.setReadOnly(ih, false);
+        InstallerSupport.deleteTree(ih);
+    }
+   
+    @Test public void TestDownload() {
+        JettyDownloadCLI.runMain(new String[] {"-v", "12.0.23"});
+    }
+}
diff --git a/jetty-cli/src/test/resources/idphome-test/conf/idp.properties b/jetty-cli/src/test/resources/idphome-test/conf/idp.properties
new file mode 100644
index 0000000..47b62e6
--- /dev/null
+++ b/jetty-cli/src/test/resources/idphome-test/conf/idp.properties
@@ -0,0 +1,2 @@
+# Load any additional property resources from a comma-delimited list
+idp.additionalProperties = /conf/services.properties
diff --git a/jetty-cli/src/test/resources/idphome-test/credentials/jetty-keystore.gpg b/jetty-cli/src/test/resources/idphome-test/credentials/jetty-keystore.gpg
new file mode 100644
index 0000000..e69de29
diff --git a/jetty-cli/src/test/resources/logback-test.xml b/jetty-cli/src/test/resources/logback-test.xml
new file mode 100644
index 0000000..042bb58
--- /dev/null
+++ b/jetty-cli/src/test/resources/logback-test.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<configuration>
+
+    <logger name="org" level="INFO"/>
+    <logger name="net.shibboleth.idp.installer" level="TRACE"/>
+
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <pattern>%level [%logger:%line] - %msg%n</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+    </appender>
+
+    <root>
+        <level value="DEBUG" />
+        <appender-ref ref="STDOUT" />
+    </root>
+    
+</configuration>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index ac94a93..d80bbea 100644
--- a/pom.xml
+++ b/pom.xml
@@ -55,6 +55,7 @@
     </dependencyManagement>
 
     <modules>
+        <module>jetty-cli</module>
         <module>jetty-impl</module>
         <module>jetty-dist</module>
     </modules>

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list