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/[email protected]/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:

org.apache.felix.shell.tui-1.5.0-SNAPSHOT.jar
org.apache.felix.shell-1.5.0-SNAPSHOT.jar
org.apache.felix.bundlerepository-1.5.0-SNAPSHOT.jar
org.apache.felix.fileinstall-2.0.3-SNAPSHOT.jar
org.apache.felix.configadmin-1.2.7-SNAPSHOT.jar

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

ls ./deploy
test.jar

- 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.
stop/1.1
start/1.1
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
            files.addAll(removed);
            // Remove no longer used checksums
            lastChecksums.remove(file);
            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 before
                     // fileinstall has been restarted.  In this case, try to 
find a listener.         
                     if (artifact.getListener() == null)                        
                       
@@ -355,7 +359,7 @@
                     artifact.setJaredDirectory(jar);
                     artifact.setJaredUrl(jaredUrl);
                     artifact.setListener(listener);
-                    artifact.setChecksum(scanner.getChecksum(file));
+                    artifact.setChecksum(scanner.checksum(file));
                     if (transformArtifact(artifact))
                     {
                         created.add(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;
/pierre


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

Reply via email to