Bug 514594: Ensure bundle location is resolved correctly when EquinoxBundleFileResolver cannot be used.
diff --git a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/OsgiAwareEmbeddedTomcat.java b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/OsgiAwareEmbeddedTomcat.java
index e4d36ae..18099fc 100644
--- a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/OsgiAwareEmbeddedTomcat.java
+++ b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/OsgiAwareEmbeddedTomcat.java
@@ -118,6 +118,8 @@
 
     private final JarScanner defaultJarScanner;
 
+    private final ServiceTracker<?, ?> urlConverterTracker;
+
     private String hostConfigDir;
 
     OsgiAwareEmbeddedTomcat(BundleContext context, ServiceTracker<?, ?> urlConverterTracker) {
@@ -126,6 +128,7 @@
             BundleFileResolverFactory.createBundleFileResolver(), context, urlConverterTracker);
         this.defaultJarScanner = new StandardJarScanner();
         this.jarScannerCustomizer = new DelegatingJarScannerCustomizer(context);
+        this.urlConverterTracker = urlConverterTracker;
     }
 
     /**
@@ -170,6 +173,10 @@
         return findEngine();
     }
 
+    ServiceTracker<?, ?> getUrlConverterTracker() {
+        return this.urlConverterTracker;
+    }
+
     private Engine findEngine() {
         Server server = getServer();
         Service[] findServices = server.findServices();
diff --git a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/TomcatServletContainer.java b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/TomcatServletContainer.java
index 4bc673a..abde872 100644
--- a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/TomcatServletContainer.java
+++ b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/TomcatServletContainer.java
@@ -102,7 +102,7 @@
 
             BundleWebappLoader loader = new BundleWebappLoader(bundle, this.classLoaderCustomizer);
             context.setLoader(loader);
-            context.setResources(new BundleWebResourceRoot(bundle));
+            context.setResources(new BundleWebResourceRoot(bundle, this.tomcat.getUrlConverterTracker()));
 
             ServletContext servletContext = context.getServletContext();
 
diff --git a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/bundleresources/BundleWebResource.java b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/bundleresources/BundleWebResource.java
index 9a93e5d..b7c086b 100644
--- a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/bundleresources/BundleWebResource.java
+++ b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/bundleresources/BundleWebResource.java
@@ -91,7 +91,7 @@
         this.bundle = bundle;
         this.fragments = getFragments(bundle);
         this.checkEntryPath = checkEntryPath();
-        File bundleLocation = this.bundleFileResolver.resolve(bundle);
+        File bundleLocation = getBundleLocation();
         if (bundleLocation != null) {
             try {
                 this.bundleLocationCanonicalPath = bundleLocation.getCanonicalPath();
@@ -103,6 +103,25 @@
         }
     }
 
+    private File getBundleLocation() {
+        File bundleLocation = this.bundleFileResolver.resolve(bundle);
+        if (bundleLocation == null) {
+            URL root = this.bundle.getEntry("/");
+            try {
+                Object converter = ((BundleWebResourceRoot) this.root).getUrlConverterTracker().getService();
+                if (converter != null) {
+                    root = ((org.eclipse.osgi.service.urlconversion.URLConverter) converter).resolve(root);
+                }
+            } catch (Exception ignore) {
+            }
+
+            if (root != null && "file".equals(root.getProtocol())) {
+                bundleLocation = new File(root.getPath());
+            }
+        }
+        return bundleLocation;
+    }
+
     private BundleWebResource(Bundle bundle, WebResourceRoot root, List<Bundle> fragments, String path, boolean checkEntryPath,
         String bundleLocationCanonicalPath, boolean isBundleLocationDirectory) {
         super(root, path);
diff --git a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/bundleresources/BundleWebResourceRoot.java b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/bundleresources/BundleWebResourceRoot.java
index b61be78..d0acf05 100644
--- a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/bundleresources/BundleWebResourceRoot.java
+++ b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/bundleresources/BundleWebResourceRoot.java
@@ -27,6 +27,7 @@
 import org.apache.catalina.WebResourceSet;

 import org.apache.catalina.webresources.StandardRoot;

 import org.osgi.framework.Bundle;

+import org.osgi.util.tracker.ServiceTracker;

 

 public class BundleWebResourceRoot extends StandardRoot {

 

@@ -34,10 +35,13 @@
 

     private final WebResource main;

 

+    private final ServiceTracker<?, ?> urlConverterTracker;

+

     private Path docBase;

 

-    public BundleWebResourceRoot(Bundle bundle) {

+    public BundleWebResourceRoot(Bundle bundle, ServiceTracker<?, ?> urlConverterTracker) {

         this.bundle = bundle;

+        this.urlConverterTracker = urlConverterTracker;

         this.main = new BundleWebResource(this.bundle, this);

     }

 

@@ -94,6 +98,10 @@
         return keyProperties.toString();

     }

 

+    ServiceTracker<?, ?> getUrlConverterTracker() {

+        return this.urlConverterTracker;

+    }

+

     @Override

     protected void registerURLStreamHandlerFactory() {

         // no-op

diff --git a/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/bundleresources/BundleWebResourceTests.java b/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/bundleresources/BundleWebResourceTests.java
index 5fc8c33..3a8b6bf 100644
--- a/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/bundleresources/BundleWebResourceTests.java
+++ b/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/bundleresources/BundleWebResourceTests.java
@@ -91,6 +91,7 @@
         BundleRevision fbundleRevision = createMock(BundleRevision.class);
         BundleWiring fbundleWiring = createMock(BundleWiring.class);
         expect(bundle.getEntry("")).andReturn(Paths.get("src/test/resources/sub/").toUri().toURL()).anyTimes();
+        expect(bundle.getEntry("/")).andReturn(Paths.get("src/test/resources/sub/").toUri().toURL()).anyTimes();
         expect(bundle.getEntry("sub/")).andReturn(Paths.get("src/test/resources/sub/").toUri().toURL()).anyTimes();
         expect(bundle.getEntryPaths("")).andReturn(createPathsEnumeration("sub/"));
         expect(bundle.getEntryPaths("sub/")).andReturn(createPathsEnumeration("sub/one.txt"));