Issue #2191 - JPMS Support

Turns out that Package.getImplementationVersion() and similar return
null when running from the module path, so the logic in StartArgs
broke and prevented Jetty to start.

Introduced ManifestUtils to retrieve the manifest file from JarFile,
so that attribute entries can be retrieved independently from the JDK
version or module-path vs class-path.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
Simone Bordet 2018-09-17 19:32:00 +02:00
parent 78894c4aae
commit 60e3562f99
4 changed files with 76 additions and 19 deletions

View File

@ -50,6 +50,7 @@
<artifact>org.eclipse.jetty:jetty-util</artifact>
<includes>
<include>org/eclipse/jetty/util/JavaVersion*</include>
<include>org/eclipse/jetty/util/ManifestUtils*</include>
<include>org/eclipse/jetty/util/TopologicalSort*</include>
</includes>
</filter>

View File

@ -59,7 +59,7 @@ import org.eclipse.jetty.start.Props.Prop;
*/
public class Module implements Comparable<Module>
{
private static final String VERSION_UNSPECIFIED = "9.2";
private static final String VERSION_UNSPECIFIED = "0.0";
static Pattern MOD_NAME = Pattern.compile("^(.*)\\.mod",Pattern.CASE_INSENSITIVE);
static Pattern SET_PROPERTY = Pattern.compile("^(#?)\\s*([^=\\s]+)=(.*)$");

View File

@ -36,12 +36,14 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.jar.Manifest;
import org.eclipse.jetty.start.Props.Prop;
import org.eclipse.jetty.start.config.ConfigSource;
import org.eclipse.jetty.start.config.ConfigSources;
import org.eclipse.jetty.start.config.DirConfigSource;
import org.eclipse.jetty.util.JavaVersion;
import org.eclipse.jetty.util.ManifestUtils;
/**
* The Arguments required to start Jetty.
@ -59,15 +61,11 @@ public class StartArgs
// Use META-INF/MANIFEST.MF versions
if (ver == null)
{
Package pkg = StartArgs.class.getPackage();
if ((pkg != null) && "Eclipse.org - Jetty".equals(pkg.getImplementationVendor()) && (pkg.getImplementationVersion() != null))
{
ver = pkg.getImplementationVersion();
if (tag == null)
{
tag = "jetty-" + ver;
}
}
ver = ManifestUtils.getManifest(StartArgs.class)
.map(Manifest::getMainAttributes)
.filter(attributes -> "Eclipse.org - Jetty".equals(attributes.getValue("Implementation-Vendor")))
.map(attributes -> attributes.getValue("Implementation-Version"))
.orElse(null);
}
// Use jetty-version.properties values
@ -82,9 +80,9 @@ public class StartArgs
props.load(in);
ver = props.getProperty("jetty.version");
}
catch (IOException ignore)
catch (IOException x)
{
StartLog.debug(ignore);
StartLog.debug(x);
}
}
}
@ -94,20 +92,21 @@ public class StartArgs
{
ver = "0.0";
if (tag == null)
{
tag = "master";
}
}
else
{
if (tag == null)
tag = "jetty-" + ver;
}
// Set Tag Defaults
if (tag == null || tag.contains("-SNAPSHOT"))
{
if (tag.contains("-SNAPSHOT"))
tag = "master";
}
VERSION = ver;
System.setProperty("jetty.version",VERSION);
System.setProperty("jetty.tag.version",tag);
System.setProperty("jetty.version", VERSION);
System.setProperty("jetty.tag.version", tag);
}
private static final String SERVER_MAIN = "org.eclipse.jetty.xml.XmlConfiguration";

View File

@ -0,0 +1,57 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.util;
import java.io.File;
import java.net.URL;
import java.security.CodeSource;
import java.util.Optional;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
public class ManifestUtils
{
private ManifestUtils()
{
}
public static Optional<Manifest> getManifest(Class<?> klass)
{
try
{
CodeSource codeSource = klass.getProtectionDomain().getCodeSource();
if (codeSource != null)
{
URL location = codeSource.getLocation();
if (location != null)
{
try (JarFile jarFile = new JarFile(new File(location.toURI())))
{
return Optional.of(jarFile.getManifest());
}
}
}
return Optional.empty();
}
catch (Throwable x)
{
return Optional.empty();
}
}
}