You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2010/01/08 11:13:32 UTC
svn commit: r897151 - in /sling/trunk/launchpad: base/
base/src/main/java/org/apache/sling/launchpad/app/
base/src/main/java/org/apache/sling/launchpad/base/shared/
base/src/main/java/org/apache/sling/launchpad/webapp/
builder/src/main/bundles/ bundles/
Author: bdelacretaz
Date: Fri Jan 8 10:13:21 2010
New Revision: 897151
URL: http://svn.apache.org/viewvc?rev=897151&view=rev
Log:
SLING-1273 - use BundleVersionInfo comparator to select most recent launcher jar file
Modified:
sling/trunk/launchpad/base/pom.xml
sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/app/Main.java
sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/shared/Loader.java
sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/webapp/SlingServlet.java
sling/trunk/launchpad/builder/src/main/bundles/list.xml
sling/trunk/launchpad/bundles/pom.xml
Modified: sling/trunk/launchpad/base/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/pom.xml?rev=897151&r1=897150&r2=897151&view=diff
==============================================================================
--- sling/trunk/launchpad/base/pom.xml (original)
+++ sling/trunk/launchpad/base/pom.xml Fri Jan 8 10:13:21 2010
@@ -97,6 +97,34 @@
</outputDirectory>
</configuration>
</execution>
+ <!-- Embed code from osgi.commons -->
+ <execution>
+ <id>extract-sling-commons-osgi</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <configuration>
+ <includeArtifactIds>org.apache.sling.commons.osgi</includeArtifactIds>
+ <excludeTransitive>true</excludeTransitive>
+ <outputDirectory>
+ ${project.build.directory}/classes
+ </outputDirectory>
+ </configuration>
+ </execution>
+ <!-- Embed osgi Version class from framework-->
+ <execution>
+ <id>extract-osgi-framework</id>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <configuration>
+ <includeArtifactIds>org.apache.felix.framework</includeArtifactIds>
+ <excludeTransitive>true</excludeTransitive>
+ <outputDirectory>
+ ${project.build.directory}/classes
+ </outputDirectory>
+ </configuration>
+ </execution>
</executions>
</plugin>
<plugin>
@@ -123,6 +151,8 @@
<includes>
<include>org/apache/sling/launchpad/base/shared/**</include>
<include>org/apache/sling/launchpad/app/**</include>
+ <include>org/apache/sling/commons/osgi/**</include>
+ <include>org/osgi/framework/Version*</include>
<include>META-INF/**</include>
</includes>
</configuration>
@@ -151,6 +181,8 @@
META-INF/**,
WEB-INF/classes/org/apache/sling/launchpad/base/shared/**,
WEB-INF/classes/org/apache/sling/launchpad/webapp/**,
+ WEB-INF/classes/org/apache/sling/commons/osgi/**,
+ WEB-INF/classes/org/osgi/framework/Version*,
WEB-INF/resources/**
</packagingIncludes>
<webResources>
@@ -220,6 +252,12 @@
<scope>provided</scope>
</dependency>
<dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.commons.osgi</artifactId>
+ <version>2.0.5-SNAPSHOT</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
Modified: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/app/Main.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/app/Main.java?rev=897151&r1=897150&r2=897151&view=diff
==============================================================================
--- sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/app/Main.java (original)
+++ sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/app/Main.java Fri Jan 8 10:13:21 2010
@@ -90,7 +90,12 @@
// The Loader helper
Loader loaderTmp = null;
try {
- loaderTmp = new Loader(slingHome);
+ loaderTmp = new Loader(slingHome) {
+ @Override
+ protected void info(String msg) {
+ Main.info(msg, null);
+ }
+ };
} catch (IllegalArgumentException iae) {
startupFailure(iae.getMessage(), null);
}
@@ -209,13 +214,8 @@
private void startSling(URL launcherJar) {
if (launcherJar != null) {
try {
- info("Checking launcher JAR in " + slingHome, null);
- if (loader.installLauncherJar(launcherJar)) {
- info("Installed or Updated launcher JAR file from "
- + launcherJar, null);
- } else {
- info("Existing launcher JAR file already up to date", null);
- }
+ info("Checking launcher JAR in folder " + slingHome, null);
+ loader.installLauncherJar(launcherJar);
} catch (IOException ioe) {
startupFailure("Failed installing " + launcherJar, ioe);
}
@@ -225,9 +225,6 @@
Object object = null;
try {
- info(
- "Loading launcher class " + SharedConstants.DEFAULT_SLING_MAIN,
- null);
object = loader.loadLauncher(SharedConstants.DEFAULT_SLING_MAIN);
} catch (IllegalArgumentException iae) {
startupFailure("Failed loading Sling class "
Modified: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/shared/Loader.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/shared/Loader.java?rev=897151&r1=897150&r2=897151&view=diff
==============================================================================
--- sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/shared/Loader.java (original)
+++ sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/shared/Loader.java Fri Jan 8 10:13:21 2010
@@ -30,8 +30,15 @@
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
import java.util.jar.JarFile;
+import org.apache.sling.commons.osgi.bundleversion.BundleVersionInfo;
+import org.apache.sling.commons.osgi.bundleversion.FileBundleVersionInfo;
+
/**
* The <code>Loader</code> class provides utility methods for the actual
* launchers to help launching the framework.
@@ -44,13 +51,6 @@
private final File slingHome;
/**
- * The current launcher JAR file in use. Set on-demand by the
- * {@link #getLauncherJarFile()} method and reset to the installed or
- * updated launcher JAR file by the {@link #installLauncherJar(URL)} method.
- */
- private File launcherJarFile;
-
- /**
* Creates a loader instance to load from the given Sling home folder.
* Besides ensuring the existence of the Sling home folder, the constructor
* also removes all but the most recent launcher JAR files from the Sling
@@ -85,6 +85,7 @@
public Object loadLauncher(String launcherClassName) {
final File launcherJarFile = getLauncherJarFile();
+ info("Loading launcher class " + launcherClassName + " from " + launcherJarFile.getName());
if (!launcherJarFile.canRead()) {
throw new IllegalArgumentException("Sling Launcher JAR "
+ launcherJarFile + " is not accessible");
@@ -137,47 +138,76 @@
/**
* Copies the contents of the launcher JAR as indicated by the URL to the
- * sling home directory and sets the last modification time stamp fo the
- * file. If the existing file is not older than the contents of the launcher
- * JAR file, the file is not replaced.
+ * sling home directory. If the existing file is is a more recent bundle version
+ * than the supplied launcher JAR file, it is is not replaced.
*
* @return <code>true</code> if the launcher JAR file has been installed or
- * updated. If the launcher JAR is already up to date,
- * <code>false</code> is returned.
+ * updated, <code>false</code> otherwise.
* @throws IOException If an error occurrs transferring the contents
*/
public boolean installLauncherJar(URL launcherJar) throws IOException {
final File currentLauncherJarFile = getLauncherJarFile();
- // check whether we have to overwrite
+ // Copy the new launcher jar to a temporary file, and
+ // extract bundle version info
final URLConnection launcherJarConn = launcherJar.openConnection();
launcherJarConn.setUseCaches(false);
- final long lastModifTime = launcherJarConn.getLastModified();
- final File newLauncherJarFile;
- if (currentLauncherJarFile.exists()) {
-
- // nothing to do if there is no update
- if (lastModifTime <= currentLauncherJarFile.lastModified()) {
- return false;
+ final File tmp = new File(slingHome, "Loader_tmp_" + System.currentTimeMillis() + SharedConstants.LAUNCHER_JAR_REL_PATH);
+ spool(launcherJarConn.getInputStream(), tmp);
+ final FileBundleVersionInfo newVi = new FileBundleVersionInfo(tmp);
+ boolean installNewLauncher = true;
+
+ try {
+ if(!newVi.isBundle()) {
+ throw new IllegalArgumentException("New launcher jar is not a bundle, cannot get version info:" + launcherJar);
}
+
+ // Compare versions to decide whether to use the existing or new launcher jar
+ if (currentLauncherJarFile.exists()) {
+ final FileBundleVersionInfo currentVi = new FileBundleVersionInfo(currentLauncherJarFile);
+ if(!currentVi.isBundle()) {
+ throw new IllegalArgumentException("Existing launcher jar is not a bundle, cannot get version info:"
+ + currentLauncherJarFile.getAbsolutePath());
+ }
- // use a new timestamped name for the new version
- newLauncherJarFile = new File(slingHome,
- SharedConstants.LAUNCHER_JAR_REL_PATH + "." + lastModifTime);
-
- } else {
-
- // create the current file
- newLauncherJarFile = currentLauncherJarFile;
+ String info = null;
+ if(currentVi.compareTo(newVi) == 0) {
+ info = "up to date";
+ installNewLauncher = false;
+ } else if(currentVi.compareTo(newVi) > 0) {
+ info = "more recent than ours";
+ installNewLauncher = false;
+ }
+
+ if(info != null) {
+ info("Existing launcher is " + info + ", using it: "
+ + getBundleInfo(currentVi) + " (" + currentLauncherJarFile.getName() + ")");
+ }
+ }
+ if(installNewLauncher) {
+ final File f = new File(tmp.getParentFile(), SharedConstants.LAUNCHER_JAR_REL_PATH + "." + System.currentTimeMillis());
+ tmp.renameTo(f);
+ info("Installing new launcher: " + launcherJar + ", " + getBundleInfo(newVi) + " (" + f.getName() + ")");
+ }
+ } finally {
+ if(tmp.exists()) {
+ tmp.delete();
+ }
}
- // store the new launcher JAR and set the last modification time
- spool(launcherJarConn.getInputStream(), newLauncherJarFile);
- newLauncherJarFile.setLastModified(lastModifTime);
- launcherJarFile = newLauncherJarFile;
-
- return true;
+ return installNewLauncher;
+ }
+
+ /** Return relevant bundle version info for logging */
+ static String getBundleInfo(BundleVersionInfo<?> v) {
+ final StringBuilder sb = new StringBuilder();
+ sb.append(v.getVersion());
+ if(v.isSnapshot()) {
+ sb.append(", Last-Modified:");
+ sb.append(new Date(v.getBundleLastModified()));
+ }
+ return sb.toString();
}
/**
@@ -190,33 +220,31 @@
private void removeOldLauncherJars() {
final File[] launcherJars = getLauncherJarFiles();
if (launcherJars != null && launcherJars.length > 0) {
-
- // start with the first entry being the newest
- File mostRecentJarFile = launcherJars[0];
- long mostRecentLastModification = mostRecentJarFile.lastModified();
- for (int i = 1; i < launcherJars.length; i++) {
-
- if (mostRecentLastModification < launcherJars[i].lastModified()) {
- // if this entry is newer than the fromer newest, remove
- // the former file and use this entry as the newest
- mostRecentJarFile.delete();
- mostRecentJarFile = launcherJars[i];
- mostRecentLastModification = mostRecentJarFile.lastModified();
-
- } else {
- // otherwise remove this entry and keep on using the current
- launcherJars[i].delete();
+
+ // Remove all files except current one
+ final File current = getLauncherJarFile();
+ for(File f : launcherJars) {
+ if(f.getAbsolutePath().equals(current.getAbsolutePath())) {
+ continue;
}
-
+ String versionInfo = null;
+ try {
+ FileBundleVersionInfo vi = new FileBundleVersionInfo(f);
+ versionInfo = getBundleInfo(vi);
+ } catch(IOException ignored) {
+ }
+ info("Deleting obsolete launcher jar: " + f.getName() + ", " + versionInfo);
+ f.delete();
}
- // fact: mostRecentJarFile is the only remaining and the most recent
- // ensure the most recent file has the common name
- if (!SharedConstants.LAUNCHER_JAR_REL_PATH.equals(mostRecentJarFile.getName())) {
+ // And ensure the current file has the standard launcher name
+ if (!SharedConstants.LAUNCHER_JAR_REL_PATH.equals(current.getName())) {
+ info("Renaming current launcher jar " + current.getName()
+ + " to " + SharedConstants.LAUNCHER_JAR_REL_PATH);
File launcherFileName = new File(
- mostRecentJarFile.getParentFile(),
+ current.getParentFile(),
SharedConstants.LAUNCHER_JAR_REL_PATH);
- mostRecentJarFile.renameTo(launcherFileName);
+ current.renameTo(launcherFileName);
}
}
}
@@ -261,62 +289,67 @@
* found in the sling home folder.
*/
private File getLauncherJarFile() {
- if (launcherJarFile == null) {
- final File[] launcherJars = getLauncherJarFiles();
- if (launcherJars == null || launcherJars.length == 0) {
-
- // return a non-existing file naming the desired primary name
- launcherJarFile = new File(slingHome,
- SharedConstants.LAUNCHER_JAR_REL_PATH);
-
- } else if (launcherJars.length == 1) {
-
- // only a single file existing, that's it
- launcherJarFile = launcherJars[0];
-
- } else {
+ File result = null;
+ final File[] launcherJars = getLauncherJarFiles();
+ if (launcherJars == null || launcherJars.length == 0) {
- // start with the first entry being the newest
- File mostRecentJarFile = launcherJars[0];
- long mostRecentLastModification = mostRecentJarFile.lastModified();
- for (int i = 1; i < launcherJars.length; i++) {
-
- // if this entry is newer than the fromer newest, use this
- // entry
- // as the newest
- if (mostRecentLastModification < launcherJars[i].lastModified()) {
- mostRecentJarFile = launcherJars[i];
- mostRecentLastModification = mostRecentJarFile.lastModified();
- }
+ // return a non-existing file naming the desired primary name
+ result = new File(slingHome,
+ SharedConstants.LAUNCHER_JAR_REL_PATH);
- }
- launcherJarFile = mostRecentJarFile;
- }
+ } else {
+ // last file is the most recent one, use it
+ result = launcherJars[launcherJars.length - 1];
}
- return launcherJarFile;
+ return result;
}
/**
* Returns all files in the <code>slingHome</code> directory which may be
- * considered as launcher JAR files. These files all start with the
+ * considered as launcher JAR files, sorted based on their bundle version
+ * information, most recent last. These files all start with the
* {@link SharedConstants#LAUNCHER_JAR_REL_PATH}. This list may be empty if
* the launcher JAR file has not been installed yet.
*
* @param slingHome The sling home directory where the launcher JAR files
* are stored
* @return The list of candidate launcher JAR files, which may be empty.
- * <code>null</code> is returned if an IO error occurrs trying to
+ * <code>null</code> is returned if an IO error occurs trying to
* list the files.
*/
private File[] getLauncherJarFiles() {
- return slingHome.listFiles(new FileFilter() {
+ // Get list of files with names starting with our prefix
+ final File[] rawList = slingHome.listFiles(new FileFilter() {
public boolean accept(File pathname) {
return pathname.isFile()
&& pathname.getName().startsWith(
SharedConstants.LAUNCHER_JAR_REL_PATH);
}
});
+
+ // Keep only those which have valid Bundle headers, and
+ // sort them according to the bundle version numbers
+ final List<FileBundleVersionInfo> list = new ArrayList<FileBundleVersionInfo>();
+ for(File f : rawList) {
+ FileBundleVersionInfo fvi = null;
+ try {
+ fvi = new FileBundleVersionInfo(f);
+ } catch(IOException ioe) {
+ // Cannot read bundle info from jar file - should never happen??
+ throw new IllegalStateException("Cannot read bundle information from loader file " + f.getAbsolutePath());
+ }
+ if(fvi.isBundle()) {
+ list.add(fvi);
+ }
+ }
+ Collections.sort(list);
+ final File [] result = new File[list.size()];
+ int i = 0;
+ for(FileBundleVersionInfo fvi : list) {
+ result[i++] = fvi.getSource();
+ }
+ return result;
}
/**
@@ -363,4 +396,8 @@
// better logging here
}
}
+
+ /** Meant to be overridden to display or log info */
+ protected void info(String msg) {
+ }
}
Modified: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/webapp/SlingServlet.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/webapp/SlingServlet.java?rev=897151&r1=897150&r2=897151&view=diff
==============================================================================
--- sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/webapp/SlingServlet.java (original)
+++ sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/webapp/SlingServlet.java Fri Jan 8 10:13:21 2010
@@ -49,6 +49,7 @@
* @see <a href="http://cwiki.apache.org/SLING/the-sling-launchpad.html">The
* Sling Launchpad</a>
*/
+@SuppressWarnings("serial")
public class SlingServlet extends GenericServlet implements Notifiable {
/**
@@ -255,7 +256,12 @@
private void startSling() {
try {
- this.loader = new Loader(slingHome);
+ this.loader = new Loader(slingHome) {
+ @Override
+ protected void info(String msg) {
+ log(msg);
+ }
+ };
} catch (IllegalArgumentException iae) {
startupFailure(null, iae);
return;
@@ -296,11 +302,7 @@
if (launcherJar != null) {
try {
log("Checking launcher JAR in " + slingHome);
- if (loader.installLauncherJar(launcherJar)) {
- log("Installed or Updated launcher JAR file from " + launcherJar);
- } else {
- log("Existing launcher JAR file is already up to date");
- }
+ loader.installLauncherJar(launcherJar);
} catch (IOException ioe) {
startupFailure("Failed installing " + launcherJar, ioe);
return;
@@ -311,8 +313,6 @@
Object object = null;
try {
- log("Loading launcher class "
- + SharedConstants.DEFAULT_SLING_SERVLET);
object = loader.loadLauncher(SharedConstants.DEFAULT_SLING_SERVLET);
} catch (IllegalArgumentException iae) {
startupFailure("Cannot load Launcher Servlet "
Modified: sling/trunk/launchpad/builder/src/main/bundles/list.xml
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/builder/src/main/bundles/list.xml?rev=897151&r1=897150&r2=897151&view=diff
==============================================================================
--- sling/trunk/launchpad/builder/src/main/bundles/list.xml (original)
+++ sling/trunk/launchpad/builder/src/main/bundles/list.xml Fri Jan 8 10:13:21 2010
@@ -19,7 +19,7 @@
<bundle>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.commons.osgi</artifactId>
- <version>2.0.4-incubator</version>
+ <version>2.0.5-SNAPSHOT</version>
</bundle>
<bundle>
<groupId>org.apache.sling</groupId>
Modified: sling/trunk/launchpad/bundles/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/bundles/pom.xml?rev=897151&r1=897150&r2=897151&view=diff
==============================================================================
--- sling/trunk/launchpad/bundles/pom.xml (original)
+++ sling/trunk/launchpad/bundles/pom.xml Fri Jan 8 10:13:21 2010
@@ -216,7 +216,7 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.commons.osgi</artifactId>
- <version>2.0.4-incubator</version>
+ <version>2.0.5-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>