bug 373202: Provide test for JarScannerCustomizer.
diff --git a/build-web-container/build.xml b/build-web-container/build.xml
index 11b31bb..55d5fa1 100644
--- a/build-web-container/build.xml
+++ b/build-web-container/build.xml
@@ -34,6 +34,7 @@
 		<pathelement location="../test-bundles/war-with-context-xml-custom-classloader"/>
 		<pathelement location="../test-bundles/war-with-context-xml-cross-context"/>
 		<pathelement location="../test-bundles/war-with-annotations"/>
+		<pathelement location="../test-bundles/customizer-bundle"/>
 	</path>
 
 	<path id="doc.bundles">
diff --git a/org.eclipse.gemini.web.test/src/test/java/org/eclipse/gemini/web/test/tomcat/TomcatServletContainerTests.java b/org.eclipse.gemini.web.test/src/test/java/org/eclipse/gemini/web/test/tomcat/TomcatServletContainerTests.java
index 8d7f08a..a702605 100644
--- a/org.eclipse.gemini.web.test/src/test/java/org/eclipse/gemini/web/test/tomcat/TomcatServletContainerTests.java
+++ b/org.eclipse.gemini.web.test/src/test/java/org/eclipse/gemini/web/test/tomcat/TomcatServletContainerTests.java
@@ -91,6 +91,8 @@
 
     private static final String LOCATION_WAR_WITH_ANNOTATIONS = "../org.eclipse.gemini.web.test/target/resources/war-with-annotations.war?Web-ContextPath=/war-with-annotations";
 
+    private static final String LOCATION_BUNDLE_CUSTOMIZER = "file:../org.eclipse.gemini.web.test/target/resources/customizer-bundle.jar";
+
     private BundleContext bundleContext;
 
     private ServletContainer container;
@@ -504,6 +506,25 @@
     }
 
     @Test
+    public void testCustomizers() throws Exception {
+        Bundle customizer = this.bundleContext.installBundle(LOCATION_BUNDLE_CUSTOMIZER);
+        customizer.start();
+
+        Bundle bundle = this.bundleContext.installBundle(LOCATION_WAR_WITH_SERVLET);
+        bundle.start();
+
+        WebApplicationHandle handle = this.container.createWebApplication("/war-with-servlet", bundle);
+        this.container.startWebApplication(handle);
+        try {
+            validateURL("http://localhost:8080/war-with-servlet/CustomServlet");
+        } finally {
+            this.container.stopWebApplication(handle);
+            bundle.uninstall();
+            customizer.uninstall();
+        }
+    }
+
+    @Test
     public void testServletContainerWithCustomDefaultWebXml() throws Exception {
         File tomcatServerXml = new File("target/config/tomcat-server.xml");
         createFileWithContent(tomcatServerXml, "");
diff --git a/test-bundles/build.properties b/test-bundles/build.properties
index 9008bf0..6c4d378 100644
--- a/test-bundles/build.properties
+++ b/test-bundles/build.properties
@@ -5,7 +5,7 @@
 ivy.cache.dir=${basedir}/../../${ivy.cache}

 integration.repo.dir=${basedir}/../../integration-repo

 disable.bundlor=true

-source.version=1.5

+source.version=1.6

 test.vm.args= -Xmx1024M -XX:MaxPermSize=512M -XX:+HeapDumpOnOutOfMemoryError

 findbugs.enforce=true

 clover.enforce=true

diff --git a/test-bundles/customizer-bundle/.classpath b/test-bundles/customizer-bundle/.classpath
new file mode 100755
index 0000000..12d699e
--- /dev/null
+++ b/test-bundles/customizer-bundle/.classpath
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<classpath>

+	<classpathentry kind="src" path="src/main/java"/>

+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>

+	<classpathentry kind="var" path="WEB_CONTAINER_IVY_CACHE/org.apache.tomcat/com.springsource.org.apache.tomcat.api/7.0.21/com.springsource.org.apache.tomcat.api-7.0.21.jar" sourcepath="/WEB_CONTAINER_IVY_CACHE/org.apache.tomcat/com.springsource.org.apache.tomcat.api/7.0.21/com.springsource.org.apache.tomcat.api-sources-7.0.21.jar"/>

+	<classpathentry kind="var" path="WEB_CONTAINER_IVY_CACHE/org.eclipse.osgi/org.eclipse.osgi/3.7.0.v20110613/org.eclipse.osgi-3.7.0.v20110613.jar" sourcepath="/WEB_CONTAINER_IVY_CACHE/org.eclipse.osgi/org.eclipse.osgi/3.7.0.v20110613/org.eclipse.osgi-sources-3.7.0.v20110613.jar"/>

+	<classpathentry kind="var" path="WEB_CONTAINER_IVY_CACHE/org.eclipse.gemini.web/org.eclipse.gemini.web.tomcat/2.1.0.M02/org.eclipse.gemini.web.tomcat-2.1.0.M02.jar" sourcepath="/WEB_CONTAINER_IVY_CACHE/org.eclipse.gemini.web/org.eclipse.gemini.web.tomcat/2.1.0.M02/org.eclipse.gemini.web.tomcat-sources-2.1.0.M02.jar"/>

+	<classpathentry kind="var" path="WEB_CONTAINER_IVY_CACHE/javax.servlet/javax.servlet/3.0.0.v201103241009/javax.servlet-3.0.0.v201103241009.jar" sourcepath="/WEB_CONTAINER_IVY_CACHE/javax.servlet/javax.servlet/3.0.0.v201103241009/javax.servlet-sources-3.0.0.v201103241009.jar"/>

+	<classpathentry kind="output" path="target"/>

+</classpath>

diff --git a/test-bundles/customizer-bundle/.project b/test-bundles/customizer-bundle/.project
new file mode 100755
index 0000000..d713fcc
--- /dev/null
+++ b/test-bundles/customizer-bundle/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>customizer-bundle</name>

+	<comment></comment>

+	<projects>

+	</projects>

+	<buildSpec>

+		<buildCommand>

+			<name>org.eclipse.jdt.core.javabuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+	</buildSpec>

+	<natures>

+		<nature>org.eclipse.jdt.core.javanature</nature>

+	</natures>

+</projectDescription>

diff --git a/test-bundles/customizer-bundle/build.xml b/test-bundles/customizer-bundle/build.xml
new file mode 100755
index 0000000..be1464e
--- /dev/null
+++ b/test-bundles/customizer-bundle/build.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="customizer-bundle">
+
+	<property file="${basedir}/../build.properties"/>
+	<property file="${basedir}/../../build.versions"/>
+	<property name="jar.output.dir" value="${basedir}/../../org.eclipse.gemini.web.test/target/resources"/>
+	<import file="${basedir}/../../virgo-build/standard/default.xml"/>
+
+</project>
diff --git a/test-bundles/customizer-bundle/ivy.xml b/test-bundles/customizer-bundle/ivy.xml
new file mode 100755
index 0000000..6980ccf
--- /dev/null
+++ b/test-bundles/customizer-bundle/ivy.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?xml-stylesheet type="text/xsl" href="http://ivyrep.jayasoft.org/ivy-doc.xsl"?>
+<ivy-module
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:noNamespaceSchemaLocation="http://incubator.apache.org/ivy/schemas/ivy.xsd"
+        version="1.3">
+
+    <info organisation="org.eclipse.gemini.web" module="${ant.project.name}"/>
+
+    <configurations>
+        <include file="${virgo.build.dir}/common/default-ivy-configurations.xml"/>
+    </configurations>
+
+    <publications>
+        <artifact name="${ant.project.name}"/>
+        <artifact name="${ant.project.name}-sources" type="src" ext="jar"/>
+    </publications>
+
+    <dependencies>
+		<dependency org="javax.servlet" name="javax.servlet" rev="${javax.servlet}" conf="compile->runtime"/>
+		<dependency org="org.apache.tomcat" name="com.springsource.org.apache.tomcat.api" rev="${org.apache.tomcat}" conf="compile->runtime"/>
+		<dependency org="org.eclipse.osgi" name="org.eclipse.osgi" rev="${org.eclipse.osgi}" conf="compile->runtime"/>
+		<dependency org="org.eclipse.gemini.web" name="org.eclipse.gemini.web.tomcat" rev="2.1.0.M02" conf="compile->runtime"/>
+    </dependencies>
+
+</ivy-module>
diff --git a/test-bundles/customizer-bundle/src/main/java/org/eclipse/gemini/web/Activator.java b/test-bundles/customizer-bundle/src/main/java/org/eclipse/gemini/web/Activator.java
new file mode 100755
index 0000000..72148d5
--- /dev/null
+++ b/test-bundles/customizer-bundle/src/main/java/org/eclipse/gemini/web/Activator.java
@@ -0,0 +1,40 @@
+/*******************************************************************************

+ * Copyright (c) 2012 SAP AG

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Apache License v2.0 which accompanies this distribution. 

+ * The Eclipse Public License is available at

+ *   http://www.eclipse.org/legal/epl-v10.html

+ * and the Apache License v2.0 is available at 

+ *   http://www.opensource.org/licenses/apache2.0.php.

+ * You may elect to redistribute this code under either of these licenses.  

+ *

+ * Contributors:

+ *   Violeta Georgieva - initial contribution

+ *******************************************************************************/

+

+package org.eclipse.gemini.web;

+

+import org.eclipse.gemini.web.tomcat.spi.ClassLoaderCustomizer;

+import org.eclipse.gemini.web.tomcat.spi.JarScannerCustomizer;

+import org.osgi.framework.BundleActivator;

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.ServiceRegistration;

+

+public class Activator implements BundleActivator {

+

+    private ServiceRegistration<?> sr;

+

+    @Override

+    public void start(BundleContext context) throws Exception {

+        this.sr = context.registerService(new String[] { ClassLoaderCustomizer.class.getName(), JarScannerCustomizer.class.getName() },

+            new Customizer(), null);

+    }

+

+    @Override

+    public void stop(BundleContext context) throws Exception {

+        this.sr.unregister();

+    }

+

+}

diff --git a/test-bundles/customizer-bundle/src/main/java/org/eclipse/gemini/web/BundleJarScanner.java b/test-bundles/customizer-bundle/src/main/java/org/eclipse/gemini/web/BundleJarScanner.java
new file mode 100755
index 0000000..1157648
--- /dev/null
+++ b/test-bundles/customizer-bundle/src/main/java/org/eclipse/gemini/web/BundleJarScanner.java
@@ -0,0 +1,131 @@
+/*******************************************************************************

+ * Copyright (c) 2012 SAP AG

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Apache License v2.0 which accompanies this distribution. 

+ * The Eclipse Public License is available at

+ *   http://www.eclipse.org/legal/epl-v10.html

+ * and the Apache License v2.0 is available at 

+ *   http://www.opensource.org/licenses/apache2.0.php.

+ * You may elect to redistribute this code under either of these licenses.  

+ *

+ * Contributors:

+ *   Violeta Georgieva - initial contribution

+ *******************************************************************************/

+

+package org.eclipse.gemini.web;

+

+import java.io.File;

+import java.io.IOException;

+import java.net.JarURLConnection;

+import java.net.MalformedURLException;

+import java.net.URL;

+import java.net.URLConnection;

+import java.util.Set;

+

+import javax.servlet.ServletContext;

+

+import org.apache.tomcat.JarScanner;

+import org.apache.tomcat.JarScannerCallback;

+import org.eclipse.osgi.baseadaptor.BaseData;

+import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile;

+import org.eclipse.osgi.framework.adaptor.BundleData;

+import org.eclipse.osgi.framework.internal.core.BundleHost;

+import org.osgi.framework.Bundle;

+import org.osgi.framework.FrameworkUtil;

+

+public class BundleJarScanner implements JarScanner {

+

+    private static final String JAR_URL_SUFFIX = "!/";

+

+    private static final String JAR_URL_PREFIX = "jar:";

+

+    private static final String REFERENCE_URL_PREFIX = "reference";

+

+    @Override

+    public void scan(ServletContext servletContext, ClassLoader classLoader, JarScannerCallback jarScannerCallback, Set<String> jarsToSkip) {

+        Bundle bundle = FrameworkUtil.getBundle(this.getClass());

+        scanBundle(bundle, jarScannerCallback);

+    }

+

+    private void scanBundle(Bundle bundle, JarScannerCallback callback) {

+        File bundleFile = resolve(bundle);

+        if (bundleFile != null) {

+            scanBundleFile(bundleFile, callback);

+        } else {

+            scanJarUrlConnection(bundle, callback);

+        }

+    }

+

+    private void scanJarUrlConnection(Bundle bundle, JarScannerCallback callback) {

+        URL bundleUrl;

+        String bundleLocation = bundle.getLocation();

+        try {

+            bundleUrl = new URL(bundleLocation);

+            if (REFERENCE_URL_PREFIX.equals(bundleUrl.getProtocol())) {

+                bundleUrl = new URL(JAR_URL_PREFIX + bundleUrl.getFile() + JAR_URL_SUFFIX);

+            } else {

+                bundleUrl = new URL(JAR_URL_PREFIX + bundleLocation + JAR_URL_SUFFIX);

+            }

+        } catch (MalformedURLException e) {

+            System.out.println("Failed to create jar: url for bundle location " + bundleLocation);

+            return;

+        }

+

+        scanBundleUrl(bundleUrl, callback);

+    }

+

+    private void scanBundleFile(File bundleFile, JarScannerCallback callback) {

+        if (bundleFile.isDirectory()) {

+            try {

+                callback.scan(bundleFile);

+            } catch (IOException e) {

+                System.out.println("Failure when attempting to scan bundle file '" + bundleFile + "':" + e.getMessage());

+            }

+        } else {

+            URL bundleUrl;

+            try {

+                bundleUrl = new URL(JAR_URL_PREFIX + bundleFile.toURI().toURL() + JAR_URL_SUFFIX);

+            } catch (MalformedURLException e) {

+                System.out.println("Failed to create jar: url for bundle file " + bundleFile);

+                return;

+            }

+            scanBundleUrl(bundleUrl, callback);

+        }

+    }

+

+    private void scanBundleUrl(URL url, JarScannerCallback callback) {

+        try {

+            URLConnection connection = url.openConnection();

+

+            if (connection instanceof JarURLConnection) {

+                callback.scan((JarURLConnection) connection);

+            }

+        } catch (IOException e) {

+            System.out.println("Failure when attempting to scan bundle via jar URL '" + url + "':" + e.getMessage());

+        }

+    }

+

+    private File resolve(Bundle bundle) {

+        BundleFile bundleFile = getBundleFile(bundle);

+        if (bundleFile != null) {

+            File file = bundleFile.getBaseFile();

+            System.out.println("Resolved bundle '" + bundle.getSymbolicName() + "' to file '" + file.getAbsolutePath() + "'");

+            return file;

+        }

+        return null;

+    }

+

+    private BundleFile getBundleFile(Bundle bundle) {

+        if (bundle instanceof BundleHost) {

+            BundleHost bh = (BundleHost) bundle;

+            BundleData bundleData = bh.getBundleData();

+            if (bundleData instanceof BaseData) {

+                return ((BaseData) bundleData).getBundleFile();

+            }

+        }

+        return null;

+    }

+

+}

diff --git a/test-bundles/customizer-bundle/src/main/java/org/eclipse/gemini/web/BundleServletContainerInitializer.java b/test-bundles/customizer-bundle/src/main/java/org/eclipse/gemini/web/BundleServletContainerInitializer.java
new file mode 100755
index 0000000..90c1861
--- /dev/null
+++ b/test-bundles/customizer-bundle/src/main/java/org/eclipse/gemini/web/BundleServletContainerInitializer.java
@@ -0,0 +1,34 @@
+/*******************************************************************************

+ * Copyright (c) 2012 SAP AG

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Apache License v2.0 which accompanies this distribution. 

+ * The Eclipse Public License is available at

+ *   http://www.eclipse.org/legal/epl-v10.html

+ * and the Apache License v2.0 is available at 

+ *   http://www.opensource.org/licenses/apache2.0.php.

+ * You may elect to redistribute this code under either of these licenses.  

+ *

+ * Contributors:

+ *   Violeta Georgieva - initial contribution

+ *******************************************************************************/

+

+package org.eclipse.gemini.web;

+

+import java.util.Set;

+

+import javax.servlet.ServletContainerInitializer;

+import javax.servlet.ServletContext;

+import javax.servlet.ServletException;

+import javax.servlet.ServletRegistration;

+

+public class BundleServletContainerInitializer implements ServletContainerInitializer {

+

+    @Override

+    public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {

+        ServletRegistration servletRegistration = ctx.addServlet("CustomServlet", new CustomServlet());

+        servletRegistration.addMapping("/CustomServlet");

+    }

+

+}

diff --git a/test-bundles/customizer-bundle/src/main/java/org/eclipse/gemini/web/CustomServlet.java b/test-bundles/customizer-bundle/src/main/java/org/eclipse/gemini/web/CustomServlet.java
new file mode 100755
index 0000000..5f0abb8
--- /dev/null
+++ b/test-bundles/customizer-bundle/src/main/java/org/eclipse/gemini/web/CustomServlet.java
@@ -0,0 +1,35 @@
+/*******************************************************************************

+ * Copyright (c) 2012 SAP AG

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Apache License v2.0 which accompanies this distribution. 

+ * The Eclipse Public License is available at

+ *   http://www.eclipse.org/legal/epl-v10.html

+ * and the Apache License v2.0 is available at 

+ *   http://www.opensource.org/licenses/apache2.0.php.

+ * You may elect to redistribute this code under either of these licenses.  

+ *

+ * Contributors:

+ *   Violeta Georgieva - initial contribution

+ *******************************************************************************/

+

+package org.eclipse.gemini.web;

+

+import java.io.IOException;

+

+import javax.servlet.ServletException;

+import javax.servlet.http.HttpServlet;

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+public class CustomServlet extends HttpServlet {

+

+    private static final long serialVersionUID = 3476948383756233572L;

+

+    @Override

+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

+        resp.getWriter().println("Servlet added by ServletContainerInitializer.");

+    }

+

+}

diff --git a/test-bundles/customizer-bundle/src/main/java/org/eclipse/gemini/web/Customizer.java b/test-bundles/customizer-bundle/src/main/java/org/eclipse/gemini/web/Customizer.java
new file mode 100755
index 0000000..720792e
--- /dev/null
+++ b/test-bundles/customizer-bundle/src/main/java/org/eclipse/gemini/web/Customizer.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2012 SAP AG
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Apache License v2.0 which accompanies this distribution. 
+ * The Eclipse Public License is available at
+ *   http://www.eclipse.org/legal/epl-v10.html
+ * and the Apache License v2.0 is available at 
+ *   http://www.opensource.org/licenses/apache2.0.php.
+ * You may elect to redistribute this code under either of these licenses.  
+ *
+ * Contributors:
+ *   Violeta Georgieva - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.gemini.web;
+
+import java.lang.instrument.ClassFileTransformer;
+
+import org.apache.tomcat.JarScanner;
+import org.eclipse.gemini.web.tomcat.spi.ClassLoaderCustomizer;
+import org.eclipse.gemini.web.tomcat.spi.JarScannerCustomizer;
+import org.osgi.framework.Bundle;
+
+public class Customizer implements ClassLoaderCustomizer, JarScannerCustomizer {
+
+    @Override
+    public ClassLoader[] extendClassLoaderChain(Bundle bundle) {
+        return new ClassLoader[] { this.getClass().getClassLoader() };
+    }
+
+    @Override
+    public void addClassFileTransformer(ClassFileTransformer transformer, Bundle bundle) {
+        // no-op
+    }
+
+    @Override
+    public ClassLoader createThrowawayClassLoader(Bundle bundle) {
+        // no-op
+        return null;
+    }
+
+    @Override
+    public JarScanner[] extendJarScannerChain(Bundle bundle) {
+        return new JarScanner[] { new BundleJarScanner() };
+    }
+}
\ No newline at end of file
diff --git a/test-bundles/customizer-bundle/src/main/resources/META-INF/MANIFEST.MF b/test-bundles/customizer-bundle/src/main/resources/META-INF/MANIFEST.MF
new file mode 100755
index 0000000..a33c08a
--- /dev/null
+++ b/test-bundles/customizer-bundle/src/main/resources/META-INF/MANIFEST.MF
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: Customizer-bundle
+Bundle-Version: 1.0.0
+Import-Package: org.apache.tomcat,
+ org.eclipse.gemini.web.tomcat.spi,
+ org.osgi.framework,
+ javax.servlet,
+ javax.servlet.http,
+ org.eclipse.osgi.baseadaptor,
+ org.eclipse.osgi.baseadaptor.bundlefile,
+ org.eclipse.osgi.framework.adaptor,
+ org.eclipse.osgi.framework.internal.core
+Bundle-Activator: org.eclipse.gemini.web.Activator  
+ 
+
diff --git a/test-bundles/customizer-bundle/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer b/test-bundles/customizer-bundle/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer
new file mode 100755
index 0000000..2c6aa78
--- /dev/null
+++ b/test-bundles/customizer-bundle/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer
@@ -0,0 +1 @@
+org.eclipse.gemini.web.BundleServletContainerInitializer
\ No newline at end of file
diff --git a/test-bundles/customizer-bundle/template.mf b/test-bundles/customizer-bundle/template.mf
new file mode 100755
index 0000000..eb49210
--- /dev/null
+++ b/test-bundles/customizer-bundle/template.mf
@@ -0,0 +1,10 @@
+Bundle-ManifestVersion: 2
+Bundle-Name: Customizer-bundle
+Bundle-SymbolicName: Customizer-bundle
+Bundle-Version: $version
+Import-Template: org.eclipse.gemini.web.*;version="${version}",
+ org.apache.tomcat.*;version="${org.apache.tomcat}",
+ org.osgi.framework.*;version="0",
+ org.eclipse.osgi.*;version="0",
+ javax.servlet.*;version="3.0.0"
+Bundle-Activator: org.eclipse.gemini.web.Activator
diff --git a/test-bundles/war-with-servlet/src/main/webapp/WEB-INF/web.xml b/test-bundles/war-with-servlet/src/main/webapp/WEB-INF/web.xml
index 094445d..2a746f3 100644
--- a/test-bundles/war-with-servlet/src/main/webapp/WEB-INF/web.xml
+++ b/test-bundles/war-with-servlet/src/main/webapp/WEB-INF/web.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
 <web-app xmlns="http://java.sun.com/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
-    version="2.5">
+    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+    version="3.0">
 
   
     <servlet>