felix-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Pierre De Rop (JIRA)" <j...@apache.org>
Subject [jira] Created: (FELIX-1776) FileInstall starts already installed bundles twice
Date Tue, 20 Oct 2009 06:46:59 GMT
FileInstall starts already installed bundles twice

                 Key: FELIX-1776
                 URL: https://issues.apache.org/jira/browse/FELIX-1776
             Project: Felix
          Issue Type: Bug
          Components: File Install
            Reporter: Pierre De Rop

This issue is described here: http://www.mail-archive.com/dev@felix.apache.org/msg13194.html

When the fwk is started without cleaning the cache, and when some bundles are already installed,
then fileinstall starts them twice.

Here is what I did in order to reproduce the problem

- I first did a simple "Test" bundle with the following activator:

public class Activator implements BundleActivator {
  public void start(BundleContext ctx) throws Exception {
    System.out.printlnp("start/version 1.0");

  public void stop(BundleContext ctx) throws Exception {
    System.out.printlnp("stop/version 1.0");

- in my "bundle" directory, I have:


- in the directory which fileinstall polls for updated bundles, I only have my simple test.jar

ls ./deploy

- Now, I start the fwk (from the trunk) with a cleaned cache:

rm -rf felix-cache
java -jar bin/felix.jar

{felix.fileinstall.poll (ms) = 2000, felix.fileinstall.dir = /home/nxuser/work/osgi/felix-trunk/main/deploy,
felix.fileinstall.debug = -1, felix.fileinstall.bundles.new.start = true, felix.fileinstall.tmpdir
= ./tmp, felix.fileinstall.filter = null}
-> Installed deploy/test.jar
start/version 1.0
Started bundle: file:/home/nxuser/work/osgi/felix-trunk/main/deploy/test.jar

- I stop the fwk, and recompile my test bundle

- I restart the fwk, without cleaning the cache, and I have this

java -jar bin/felix.jar

Welcome to Felix

{felix.fileinstall.poll (ms) = 2000, felix.fileinstall.dir = /home/nxuser/work/osgi/felix-trunk/main/deploy,
felix.fileinstall.debug = -1, felix.fileinstall.bundles.new.start = true, felix.fileinstall.tmpdir
= ./tmp, felix.fileinstall.filter = null}
Updated /home/nxuser/work/osgi/felix-trunk/main/deploy/test.jar
start/version 1.1
Started bundle: file:/home/nxuser/work/osgi/felix-trunk/main/deploy/test.jar
-> A bundle with the same symbolic name (test.dm) and version (1.0) is already installed.
 Updating this bundle instead.
Installed deploy/test.jar
Started bundle: file:/home/nxuser/work/osgi/felix-trunk/main/deploy/test.jar

I have attached a proposed patch to this issue, but please read it carefully because I am
not sure about it.
Indeed, I suspect that the problem comes from the Scanner.run method, where the "storedChecksums"
is removed from the map:

        for (Iterator it = removed.iterator(); it.hasNext();)
            File file = (File) it.next();
            // Make sure we'll handle a file that has been deleted
            // Remove no longer used checksums
            storedChecksums.remove(file); -> why doing so ? The getChecksum methods will
returns 0

Because of the "storedChecksums.remove(file)" call, the scanner.getChecksum(File f) method
always returns 0.
However, I'm not sure if this is really the bug, but because of this checksum removal, DIrectoryWatcher
is no longer able to retrieve the correct checksum for tracked bundles.

So, I did the following safe patches in DirectoryWatcher.java and everything sounds to work
fine now:
(in fact, I always call scanner.checksum(File) instead of scanner.getChecksum(File) ...)

svn diff src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java
@@ -297,7 +297,11 @@                                                                     
                 // File has been modified                                               
                 if (exists && artifact != null)                                 
-                    artifact.setChecksum(scanner.getChecksum(file));                    
+                    if (artifact.getChecksum() == scanner.checksum(file)) {             
+                        continue;                                                       
+                    }                                                                   
+                    artifact.setChecksum(scanner.checksum(file));                       
                     // If there's no listener, this is because this artifact has been installed
                     // fileinstall has been restarted.  In this case, try to find a listener.
                     if (artifact.getListener() == null)                                 
@@ -355,7 +359,7 @@
-                    artifact.setChecksum(scanner.getChecksum(file));
+                    artifact.setChecksum(scanner.checksum(file));
                     if (transformArtifact(artifact))

Now, there is another issue I noticed.
It's not related to the current issue, and it's another one:
in the Utils.java, the getBundleKey(Bundle b) returns a string which is supposed to uniquely
identify the bundle 
(that is: Bundle-SymbolicName/Bundle Version).

However, it may happen that a bundle is updated with a new bundle version ... that's why I
reworked this method,
in order to just simply return the path name of the bundle:

svn diff src/main/java/org/apache/felix/fileinstall/internal/Util.java 
     private static String getBundleKey(Bundle b)
-        StringBuffer sb = new StringBuffer();
-        sb.append(b.getSymbolicName()).append("_");
-        String version = (String) b.getHeaders().get(Constants.BUNDLE_VERSION);
-        sb.append(version != null ? version : Version.emptyVersion.toString());
-        return sb.toString();
+        return getFile(b).getPath().replace(File.separator, "_");

+    private static File getFile(Bundle b)
+    {
+        try
+        {
+            String location = b.getLocation();
+            if (location.startsWith("file:"))
+            {
+                return new File(location.substring("file:".length()));
+            }
+            return new File(new URL(location).getFile());
+        }
+        catch (MalformedURLException e)
+        {
+            throw new RuntimeException("Could not get location from bundle "
+                + b.getLocation(), e);
+        }
+    }

Hope this helps;

This message is automatically generated by JIRA.
You can reply to this email to add a comment to the issue online.

View raw message