Commit 4cdab6a2 authored by Guus der Kinderen's avatar Guus der Kinderen Committed by daryl herzmann

OF-1425: Allow a min Java version to be defined for a plugin. (#915)

parent b669b608
...@@ -23,6 +23,7 @@ import org.dom4j.io.SAXReader; ...@@ -23,6 +23,7 @@ import org.dom4j.io.SAXReader;
import org.jivesoftware.admin.AdminConsole; import org.jivesoftware.admin.AdminConsole;
import org.jivesoftware.database.DbConnectionManager; import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.util.JavaSpecVersion;
import org.jivesoftware.util.JiveGlobals; import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.LocaleUtils; import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Version; import org.jivesoftware.util.Version;
...@@ -453,6 +454,18 @@ public class PluginManager ...@@ -453,6 +454,18 @@ public class PluginManager
} }
} }
// See if the plugin specifies a minimum version of Java required to run.
if ( metadata.getMinJavaVersion() != null )
{
final JavaSpecVersion runtimeVersion = new JavaSpecVersion( System.getProperty( "java.specification.version" ) );
if ( metadata.getMinJavaVersion().isNewerThan( runtimeVersion ) )
{
Log.warn( "Ignoring plugin '{}': requires Java specification version {}. Openfire is currently running in Java {}.", canonicalName, metadata.getMinJavaVersion(), System.getProperty( "java.specification.version" ) );
failureToLoadCount.put( canonicalName, Integer.MAX_VALUE ); // Don't retry - this cannot be recovered from.
return false;
}
}
// Properties to be used to load external resources. When set, plugin is considered to run in DEV mode. // Properties to be used to load external resources. When set, plugin is considered to run in DEV mode.
final String devModeClassesDir = System.getProperty( canonicalName + ".classes" ); final String devModeClassesDir = System.getProperty( canonicalName + ".classes" );
final String devModewebRoot = System.getProperty( canonicalName + ".webRoot" ); final String devModewebRoot = System.getProperty( canonicalName + ".webRoot" );
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
package org.jivesoftware.openfire.container; package org.jivesoftware.openfire.container;
import org.jivesoftware.util.JavaSpecVersion;
import org.jivesoftware.util.Version; import org.jivesoftware.util.Version;
import java.net.URL; import java.net.URL;
...@@ -83,6 +84,11 @@ public class PluginMetadata ...@@ -83,6 +84,11 @@ public class PluginMetadata
*/ */
private final Version priorToServerVersion; private final Version priorToServerVersion;
/**
* Minimum Java (specification) version (inclusive( required by this plugin as specified in plugin.xml.
*/
private final JavaSpecVersion minJavaVersion;
/** /**
* Constructs a metadata object based on a plugin. * Constructs a metadata object based on a plugin.
* *
...@@ -104,7 +110,8 @@ public class PluginMetadata ...@@ -104,7 +110,8 @@ public class PluginMetadata
PluginMetadataHelper.getReadme( pluginDir ), PluginMetadataHelper.getReadme( pluginDir ),
PluginMetadataHelper.getLicense( pluginDir ), PluginMetadataHelper.getLicense( pluginDir ),
PluginMetadataHelper.getMinServerVersion( pluginDir ), PluginMetadataHelper.getMinServerVersion( pluginDir ),
PluginMetadataHelper.getPriorToServerVersion( pluginDir ) PluginMetadataHelper.getPriorToServerVersion( pluginDir ),
PluginMetadataHelper.getMinJavaVersion( pluginDir )
); );
} }
...@@ -129,13 +136,15 @@ public class PluginMetadata ...@@ -129,13 +136,15 @@ public class PluginMetadata
PluginMetadataHelper.getReadme( plugin ), PluginMetadataHelper.getReadme( plugin ),
PluginMetadataHelper.getLicense( plugin ), PluginMetadataHelper.getLicense( plugin ),
PluginMetadataHelper.getMinServerVersion( plugin ), PluginMetadataHelper.getMinServerVersion( plugin ),
PluginMetadataHelper.getPriorToServerVersion( plugin ) PluginMetadataHelper.getPriorToServerVersion( plugin ),
PluginMetadataHelper.getMinJavaVersion( plugin )
); );
} }
public PluginMetadata( String name, String canonicalName, String description, Version version, String author, public PluginMetadata( String name, String canonicalName, String description, Version version, String author,
URL icon, URL changelog, URL readme, String license, URL icon, URL changelog, URL readme, String license,
Version minServerVersion, Version priorToServerVersion ) Version minServerVersion, Version priorToServerVersion, JavaSpecVersion minJavaVersion )
{ {
this.name = name; this.name = name;
this.canonicalName = canonicalName; this.canonicalName = canonicalName;
...@@ -148,6 +157,7 @@ public class PluginMetadata ...@@ -148,6 +157,7 @@ public class PluginMetadata
this.license = license; this.license = license;
this.minServerVersion = minServerVersion; this.minServerVersion = minServerVersion;
this.priorToServerVersion = priorToServerVersion; this.priorToServerVersion = priorToServerVersion;
this.minJavaVersion = minJavaVersion;
} }
public String getName() public String getName()
...@@ -205,6 +215,11 @@ public class PluginMetadata ...@@ -205,6 +215,11 @@ public class PluginMetadata
return priorToServerVersion; return priorToServerVersion;
} }
public JavaSpecVersion getMinJavaVersion()
{
return minJavaVersion;
}
public String getHashCode() { public String getHashCode() {
return String.valueOf( hashCode() ); return String.valueOf( hashCode() );
} }
......
...@@ -21,6 +21,7 @@ import org.dom4j.Element; ...@@ -21,6 +21,7 @@ import org.dom4j.Element;
import org.dom4j.io.SAXReader; import org.dom4j.io.SAXReader;
import org.jivesoftware.admin.AdminConsole; import org.jivesoftware.admin.AdminConsole;
import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.util.JavaSpecVersion;
import org.jivesoftware.util.Version; import org.jivesoftware.util.Version;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -315,6 +316,41 @@ public class PluginMetadataHelper ...@@ -315,6 +316,41 @@ public class PluginMetadataHelper
return new Version( value ); return new Version( value );
} }
/**
* Returns the minimum Java specification version this plugin needs to run. The value is retrieved from the
* plugin.xml file of the plugin. If the value could not be found, <tt>null</tt> will be returned.
*
* Note that this method will return data only for plugins that have successfully been installed. To obtain data
* from plugin (directories) that have not (yet) been installed, refer to the overloaded method that takes a Path
* argument.
*
* @param plugin The plugin (cannot be null)
* @return the plugin's minimum Java version (possibly null).
*/
public static JavaSpecVersion getMinJavaVersion( Plugin plugin )
{
return getMinJavaVersion( XMPPServer.getInstance().getPluginManager().getPluginPath( plugin ) );
}
/**
* Returns the minimum Java specification version this plugin needs to run. The value is retrieved from the
* plugin.xml file of the plugin. If the value could not be found, <tt>null</tt> will be returned.
*
* @param pluginDir the path of the plugin directory.
* @return the plugin's minimum Java version (possibly null).
*/
public static JavaSpecVersion getMinJavaVersion( Path pluginDir )
{
final String value = getElementValue( pluginDir, "/plugin/minJavaVersion" );
if ( value == null || value.trim().isEmpty() )
{
return null;
}
return new JavaSpecVersion( value );
}
/** /**
* Returns the database schema key of a plugin, if it exists. The value is retrieved from the plugin.xml file of the * Returns the database schema key of a plugin, if it exists. The value is retrieved from the plugin.xml file of the
* plugin. If the value could not be found, <tt>null</tt> will be returned. * plugin. If the value could not be found, <tt>null</tt> will be returned.
......
...@@ -18,6 +18,7 @@ package org.jivesoftware.openfire.update; ...@@ -18,6 +18,7 @@ package org.jivesoftware.openfire.update;
import org.dom4j.Element; import org.dom4j.Element;
import org.jivesoftware.openfire.container.PluginMetadata; import org.jivesoftware.openfire.container.PluginMetadata;
import org.jivesoftware.util.JavaSpecVersion;
import org.jivesoftware.util.Version; import org.jivesoftware.util.Version;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -127,6 +128,13 @@ public class AvailablePlugin extends PluginMetadata ...@@ -127,6 +128,13 @@ public class AvailablePlugin extends PluginMetadata
priorToServerVersion = new Version( priorToServerVersionValue ); priorToServerVersion = new Version( priorToServerVersionValue );
} }
JavaSpecVersion minJavaVersion = null;
String minJavaVersionValue = plugin.attributeValue( "minJavaVersion" );
if ( minJavaVersionValue != null && !minJavaVersionValue.isEmpty() )
{
minJavaVersion = new JavaSpecVersion( minJavaVersionValue );
}
long fileSize = -1; long fileSize = -1;
String fileSizeValue = plugin.attributeValue("fileSize"); String fileSizeValue = plugin.attributeValue("fileSize");
if ( fileSizeValue != null && !fileSizeValue.isEmpty() ) if ( fileSizeValue != null && !fileSizeValue.isEmpty() )
...@@ -148,6 +156,7 @@ public class AvailablePlugin extends PluginMetadata ...@@ -148,6 +156,7 @@ public class AvailablePlugin extends PluginMetadata
license, license,
minServerVersion, minServerVersion,
priorToServerVersion, priorToServerVersion,
minJavaVersion,
downloadUrl, downloadUrl,
fileSize fileSize
); );
...@@ -155,7 +164,8 @@ public class AvailablePlugin extends PluginMetadata ...@@ -155,7 +164,8 @@ public class AvailablePlugin extends PluginMetadata
} }
public AvailablePlugin( String name, String canonicalName, String description, Version latestVersion, String author, public AvailablePlugin( String name, String canonicalName, String description, Version latestVersion, String author,
URL icon, URL changelog, URL readme, String license, URL icon, URL changelog, URL readme, String license,
Version minServerVersion, Version priorToServerVersion, URL downloadUrl, long fileSize ) { Version minServerVersion, Version priorToServerVersion, JavaSpecVersion minJavaVersion,
URL downloadUrl, long fileSize ) {
super( super(
name, name,
canonicalName, canonicalName,
...@@ -167,7 +177,8 @@ public class AvailablePlugin extends PluginMetadata ...@@ -167,7 +177,8 @@ public class AvailablePlugin extends PluginMetadata
readme, readme,
license, license,
minServerVersion, minServerVersion,
priorToServerVersion priorToServerVersion,
minJavaVersion
); );
this.downloadURL = downloadUrl; this.downloadURL = downloadUrl;
this.fileSize = fileSize; this.fileSize = fileSize;
......
/*
* Copyright (C) 2017 Ignite Realtime Foundation. All rights reserved.
*
* 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 org.jivesoftware.util;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Holds version information for Java specification (a major and minor version, eg: 1.8).
*
* @author Guus der Kinderen, guus.der.kinderen@gmail.com
*/
public final class JavaSpecVersion implements Comparable<JavaSpecVersion> {
private static final Pattern PATTERN = Pattern.compile("(\\d+)\\.(\\d+)");
/**
* The major number (ie 1.x).
*/
private final int major;
/**
* The minor version number (ie x.8).
*/
private final int minor;
/**
* Create a new version information object.
*
* @param major the major release number.
* @param minor the minor release number.
*/
public JavaSpecVersion( int major, int minor ) {
this.major = major;
this.minor = minor;
}
/**
* Create a new version from a simple version string (e.g. "1.8")
*
* @param source the version string
*/
public JavaSpecVersion( CharSequence source ) {
if (source != null) {
Matcher matcher = PATTERN.matcher(source);
if (matcher.matches()) {
major = Integer.parseInt(matcher.group(1));
minor = Integer.parseInt(matcher.group(2));
} else {
this.major = this.minor = 0;
}
} else {
this.major = this.minor = 0;
}
}
/**
* Returns the version number of this instance of Openfire as a
* String (ie major.minor.revision).
*
* @return The version as a string
*/
public String getVersionString() {
return major + "." + minor;
}
/**
* Obtain the major release number for this product.
*
* @return The major release number 1.x.x
*/
public int getMajor() {
return major;
}
/**
* Obtain the minor release number for this product.
*
* @return The minor release number x.1.x
*/
public int getMinor() {
return minor;
}
/**
* Convenience method for comparing versions
*
* @param otherVersion a verion to comapr against
*/
public boolean isNewerThan(JavaSpecVersion otherVersion) {
return this.compareTo(otherVersion) > 0;
}
@Override
public int compareTo(JavaSpecVersion that) {
if (that == null) {
return 1;
}
int result = Integer.compare(getMajor(), that.getMajor());
if (result == 0) {
result = Integer.compare(getMinor(), that.getMinor());
}
return result;
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof JavaSpecVersion )) {
return false;
}
JavaSpecVersion other = (JavaSpecVersion) o;
return Objects.equals(major, other.major)
&& Objects.equals(minor, other.minor);
}
@Override
public int hashCode() {
return Objects.hash(major, minor);
}
@Override
public String toString() {
return getVersionString();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment