diff --git a/src/main/scala/sbt/jetty/LazyJettyRun.scala.templ b/src/main/scala/sbt/jetty/LazyJettyRun.scala.templ
index 4de20ee22..41d88b60b 100644
--- a/src/main/scala/sbt/jetty/LazyJettyRun.scala.templ
+++ b/src/main/scala/sbt/jetty/LazyJettyRun.scala.templ
@@ -58,10 +58,15 @@ private object LazyJettyRun${jetty.version} extends JettyRun
def createLoader =
{
- class SbtWebAppLoader extends WebAppClassLoader(jettyLoader, webapp) { override def addURL(u: URL) = super.addURL(u) };
- val loader = new SbtWebAppLoader
- classpathURLs.foreach(loader.addURL)
- loader
+ // Jetty treats WebAppClassLoader subclasses specially and we need this special behavior.
+ // However, Jetty adds extra classpath components directly using 'addURL'.
+ // We only want the 'urls' we provide in the constructor, so 'addURL' is overridden to do nothing.
+ class SbtWebAppLoader(urls: Seq[URL]) extends WebAppClassLoader(jettyLoader, webapp)
+ {
+ urls.foreach(super.addURL)
+ override def addURL(u: URL) = {}
+ }
+ new SbtWebAppLoader(classpathURLs)
}
def setLoader() = webapp.setClassLoader(createLoader)
diff --git a/src/sbt-test/web/servlet-nodup/changes/MyServlet1.scala b/src/sbt-test/web/servlet-nodup/changes/MyServlet1.scala
new file mode 100644
index 000000000..4ebb25bf5
--- /dev/null
+++ b/src/sbt-test/web/servlet-nodup/changes/MyServlet1.scala
@@ -0,0 +1,24 @@
+package test
+
+import java.util.Collections
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+class MyServlet extends HttpServlet {
+
+ val html =
+
Hello, Scala!
+ Hello, Scala! This is a servlet.
+
+
+ override def doGet(req:HttpServletRequest, resp:HttpServletResponse) {
+ val found = Collections.list(getClass.getClassLoader.getResources("test/MyServlet.class"))
+ assert( found.size == 1, "Multiple instances of MyServlet.class on classpath")
+ resp.setContentType("text/html")
+ resp.getWriter().print(html.toString)
+ }
+ def check28(f: Int = 3) = f
+}
+
diff --git a/src/sbt-test/web/servlet-nodup/changes/MyServlet2.scala b/src/sbt-test/web/servlet-nodup/changes/MyServlet2.scala
new file mode 100644
index 000000000..a83ddcf08
--- /dev/null
+++ b/src/sbt-test/web/servlet-nodup/changes/MyServlet2.scala
@@ -0,0 +1,24 @@
+package test
+
+import java.util.Collections
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+class MyServlet extends HttpServlet {
+
+ val html =
+ Hello, Scala 2!
+ Hello, Scala 2! This is a servlet.
+
+
+ override def doGet(req:HttpServletRequest, resp:HttpServletResponse) {
+ val found = Collections.list(getClass.getClassLoader.getResources("test/MyServlet.class"))
+ assert( found.size == 1, "Multiple instances of MyServlet.class on classpath")
+ resp.setContentType("text/html")
+ resp.getWriter().print(html.toString)
+ }
+ def check28(f: Int = 3) = f
+}
+
diff --git a/src/sbt-test/web/servlet-nodup/project/build.properties b/src/sbt-test/web/servlet-nodup/project/build.properties
new file mode 100644
index 000000000..34162cdcd
--- /dev/null
+++ b/src/sbt-test/web/servlet-nodup/project/build.properties
@@ -0,0 +1,3 @@
+project.organization=tester
+project.name=sbtweb
+project.version=1.0
diff --git a/src/sbt-test/web/servlet-nodup/project/build/src/WebappBuild.scala b/src/sbt-test/web/servlet-nodup/project/build/src/WebappBuild.scala
new file mode 100644
index 000000000..4b0028732
--- /dev/null
+++ b/src/sbt-test/web/servlet-nodup/project/build/src/WebappBuild.scala
@@ -0,0 +1,25 @@
+import sbt._
+
+class WebappBuild(info: ProjectInfo) extends DefaultWebProject(info) {
+
+ override def libraryDependencies = if("jetty7".asFile.exists) jetty7Dependencies else jetty6Dependencies
+ def jetty6Dependencies =
+ Set("org.mortbay.jetty" % "servlet-api-2.5" % "6.1.14" % "provided->default",
+ "org.mortbay.jetty" % "jetty" % "6.1.14" % "test->default")
+ def jetty7Dependencies =
+ Set("javax.servlet" % "servlet-api" % "2.5" % "provided",
+ "org.eclipse.jetty" % "jetty-server" % "7.0.1.v20091125" % "test",
+ "org.eclipse.jetty" % "jetty-webapp" % "7.0.1.v20091125" % "test")
+
+ def indexURL = new java.net.URL("http://localhost:8080")
+ def indexFile = new java.io.File("index.html")
+ import Process._
+ lazy val getPage = execTask { indexURL #> indexFile }
+ lazy val checkPage = task { args => task { checkHelloWorld(args.mkString(" ")) } dependsOn getPage }
+
+ private def checkHelloWorld(checkString: String) =
+ {
+ val value = xsbt.FileUtilities.read(indexFile)
+ if(value.contains(checkString)) None else Some("index.html did not contain '" + checkString + "' :\n" +value)
+ }
+}
diff --git a/src/sbt-test/web/servlet-nodup/src/main/webapp/WEB-INF/web.xml b/src/sbt-test/web/servlet-nodup/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..441ad39bd
--- /dev/null
+++ b/src/sbt-test/web/servlet-nodup/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,18 @@
+
+
+
+ Test Web Application
+
+
+ Home
+ test.MyServlet
+
+
+ Home
+ /
+
+
+
+
diff --git a/src/sbt-test/web/servlet-nodup/test b/src/sbt-test/web/servlet-nodup/test
new file mode 100644
index 000000000..39ebb15bd
--- /dev/null
+++ b/src/sbt-test/web/servlet-nodup/test
@@ -0,0 +1,32 @@
+> ++2.8.0.Beta1
+
+$ copy-file changes/MyServlet1.scala src/main/scala/test/MyServlet.scala
+> update
+> jetty-run
+> check-page "Hello, Scala!"
+
+$ copy-file changes/MyServlet2.scala src/main/scala/test/MyServlet.scala
+
+> prepare-webapp
+> jetty-reload
+> check-page "Hello, Scala 2!"
+
+> jetty-stop
+-> check-page "Hello World 2!"
+
+# test that it works with Jetty 7 support
+$ touch jetty7
+
+$ copy-file changes/MyServlet1.scala src/main/scala/test/MyServlet.scala
+> update
+> jetty-run
+> check-page "Hello, Scala!"
+
+$ copy-file changes/MyServlet2.scala src/main/scala/test/MyServlet.scala
+
+> prepare-webapp
+> jetty-reload
+> check-page "Hello, Scala 2!"
+
+> jetty-stop
+-> check-page "Hello World 2!"
\ No newline at end of file