DoltengでS2JDBCオンリーやS2DAOオンリーでプロジェクト作成した場合に、S2TestCaseを実行しようとするとNoClassDefFoundErrorが出ると思います。原因はS2TastCaseが、ServletAPIを必要としているからです。
対処策としては、pom.xmlにgeronimo-servlet_2.4_specを追加すれば解決します。が、このエラーが出るケースは、画面側とDB側でモジュールを別けたい時だと思います。その時は、pomのscope記述にprovidedと書いておけば、デプロイ時に配布されることはありません。
エラーの内容
java.lang.NoClassDefFoundError: javax/servlet/ServletContext at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:621) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124) at java.net.URLClassLoader.defineClass(URLClassLoader.java:260) at java.net.URLClassLoader.access$000(URLClassLoader.java:56) at java.net.URLClassLoader$1.run(URLClassLoader.java:195) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at java.lang.ClassLoader.loadClass(ClassLoader.java:307) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:252) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320) at java.lang.Class.getDeclaredMethods0(Native Method) at java.lang.Class.privateGetDeclaredMethods(Class.java:2427) at java.lang.Class.getMethod0(Class.java:2670) at java.lang.Class.getMethod(Class.java:1603) at org.junit.internal.requests.ClassRequest.hasSuiteMethod(ClassRequest.java:61) at org.junit.internal.requests.ClassRequest.getRunnerClass(ClassRequest.java:50) at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:28) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:26) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:24) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:40) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:30) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:445) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196) Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletContext at java.net.URLClassLoader$1.run(URLClassLoader.java:200) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at java.lang.ClassLoader.loadClass(ClassLoader.java:307) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:252) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320) ... 27 more
対処方法
<dependency> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-servlet_2.4_spec</artifactId> <version>1.0</version> <scope>provided</scope> </dependency>
スコープの種類 via Maven2のTipsを集めるWiki
scopeには以下の値が設定できる。
compile
デフォルト
provided
デプロイ時には含めたくない場合。例えばservlet-api.jar。
runtime
実行時にのみ必要とする場合。例えばJDBCドライバ。
test
テスト時にのみ必要とする場合。例えばJUnit。
system
providedに似ている。systemPathタグでJarまでのパスを記述する必要がある。例えばJDBC標準拡張やJAASに利用する。