[ https://issues.apache.org/jira/browse/FELIX-1776?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Pierre De Rop updated FELIX-1776: --------------------------------- Attachment: fileinstall-patch.tgz attached the proposed patch > 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 > Attachments: fileinstall-patch.tgz > > > 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: > 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.