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.