Pocket

こんにちは、kikuchiです。

今の担当プロジェクトではSpringを使った開発をしているのですが、
既存メンバが作成したSpringMVCプロジェクトをベースにしてコーディングを行っています。
私自身はイチからプロジェクトを作成した経験が無かったため、今回はSpringを使用するプロジェクトの作成を行ってみたいと思います。

調べていく中で、Eclipseのプラグインに「SpringIDE」というものがあり、ベースとなるサンプルプロジェクトが簡単に作れそうだったため、こちらを利用して作成していきます。
※似たようなもので「Spring Tool Suite(STS)」というものもあります。
軽く調べてみた感じですが、「Spring開発を行うための統合開発ツール」のようなものだと解釈しています。
STSの核となるのはSpringIDEなのですが(提供元は同じ)、他にも開発作業を行う中で有用なものがあるようです。
(あまり詳しく理解してないので大雑把な説明で申し訳ないです)

【SpringIDEのインストール】

まず前提として、Eclipseを使った開発とします。
私の環境で使用しているのは、PleiadesのAll in One、4.3 Kepler Ultimate になります。

ヘルプ→Eclipseマーケットプレース
から、「SpringIDE」で検索してインストールします。

0929_1

【プロジェクトの作成】

SpringIDEをインストールすると、「新規プロジェクトの作成」ウィザードでSpringの項目が追加されていると思います。
そこからSpringプロジェクトを選択します。
Springのバージョンは、最初の「動かすためのサンプル作成」なので指定しません。

0929_2

プロジェクト名を入力し、テンプレートから「Spring MVC Project」を選択します。

0929_3

使用するパッケージ名を決めます。
最低3階層指定する必要があります。

0929_4

ポチっと完了すると、サンプルプロジェクトが作成されました。
ページにアクセスすると、現在時刻を表示するプログラムです。

0929_5

Spring固有の設定ファイルが、WEB-INF配下に格納されています。
※Path自体はWeb.xmlに記載

【サーバで実行】

Apatch Tomcatで実行します。
これで無事完了さすがEclipse先生、数々のプラグインを持ちいとも簡単に開発環境を提供してくれるそこにシビれる憧れ…
あら、404エラー

0929_6

エラー内容的には、アクセスしたURL(リクエスト先)が見つからない(=上手くデプロイされてない?)ということになりますがはて…

<アレコレすること小一時間…>

何度か作ったり消したり名前変えたりしながらやってみたところ、
どうやらプロジェクト名にアンダースコアが入っていると発生するようです。
え、本当ですか。

0929_7

ただ、リクエストURL自体にアンダースコアが入っていても問題無さそうなので、
根本的な原因は別な気がします。

変更前

	~
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
	~

変更後

	~
	@RequestMapping(value = "/test_req", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
	~

0929_8

ちょっともやもやした疑問が残りましたが、ひとまずSpringの実行環境が出来ました。
今後はサンプルをベースにSpringの設定を確認していったり、コードを追加していったりしてみたいと思います。

※以下余談
気になったので後日もう少し弄ってみました。
正常時と異常時でログを見比べると、確かに異常時ではSpringFrameworkのログが出力されてません。

■エラーになる方

2014/10/03 0:02:54 org.apache.catalina.core.AprLifecycleListener init
情報: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: E:\dev\pleiades\java\6\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;E:/dev/pleiades/eclipse/jre/bin/server;E:/dev/pleiades/eclipse/jre/bin;E:/dev/pleiades/eclipse/jre/lib/amd64;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Intel\OpenCL SDK\3.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\3.0\bin\x64;C:\Program Files (x86)\Windows Live\Shared;E:\install\VIP Access Client\;E:\dev\TortoiseSVN\bin;.;;E:\dev\pleiades\eclipse;;.
2014/10/03 0:02:55 org.apache.tomcat.util.digester.SetPropertiesRule begin
警告: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:SpringMVC_Sample' did not find a matching property.
2014/10/03 0:02:55 org.apache.coyote.AbstractProtocol init
情報: Initializing ProtocolHandler ["http-bio-8080"]
2014/10/03 0:02:55 org.apache.coyote.AbstractProtocol init
情報: Initializing ProtocolHandler ["ajp-bio-8009"]
2014/10/03 0:02:55 org.apache.catalina.startup.Catalina load
情報: Initialization processed in 323 ms
2014/10/03 0:02:55 org.apache.catalina.core.StandardService startInternal
情報: サービス Catalina を起動します
2014/10/03 0:02:55 org.apache.catalina.core.StandardEngine startInternal
情報: Starting Servlet Engine: Apache Tomcat/7.0.52
2014/10/03 0:02:55 org.apache.tomcat.websocket.server.WsSci onStartup
情報: JSR 356 WebSocket (Java WebSocket 1.0) support is not available when running on Java 6. To suppress this message, run Tomcat on Java 7, remove the WebSocket JARs from $CATALINA_HOME/lib or add the WebSocketJARs to the tomcat.util.scan.DefaultJarScanner.jarsToSkip property in $CATALINA_BASE/conf/catalina.properties. Note that the deprecated Tomcat 7 WebSocket API will be available. 
2014/10/03 0:02:55 org.apache.coyote.AbstractProtocol start
情報: Starting ProtocolHandler ["http-bio-8080"]
2014/10/03 0:02:55 org.apache.coyote.AbstractProtocol start
情報: Starting ProtocolHandler ["ajp-bio-8009"]
2014/10/03 0:02:55 org.apache.catalina.startup.Catalina start
情報: Server startup in 316 ms

■正常に動く方

2014/10/03 0:04:56 org.apache.catalina.core.AprLifecycleListener init
情報: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: E:\dev\pleiades\java\6\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;E:/dev/pleiades/eclipse/jre/bin/server;E:/dev/pleiades/eclipse/jre/bin;E:/dev/pleiades/eclipse/jre/lib/amd64;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Intel\OpenCL SDK\3.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\3.0\bin\x64;C:\Program Files (x86)\Windows Live\Shared;E:\install\VIP Access Client\;E:\dev\TortoiseSVN\bin;.;;E:\dev\pleiades\eclipse;;.
2014/10/03 0:04:56 org.apache.tomcat.util.digester.SetPropertiesRule begin
警告: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:springsample' did not find a matching property.
2014/10/03 0:04:56 org.apache.coyote.AbstractProtocol init
情報: Initializing ProtocolHandler ["http-bio-8080"]
2014/10/03 0:04:56 org.apache.coyote.AbstractProtocol init
情報: Initializing ProtocolHandler ["ajp-bio-8009"]
2014/10/03 0:04:56 org.apache.catalina.startup.Catalina load
情報: Initialization processed in 333 ms
2014/10/03 0:04:56 org.apache.catalina.core.StandardService startInternal
情報: サービス Catalina を起動します
2014/10/03 0:04:56 org.apache.catalina.core.StandardEngine startInternal
情報: Starting Servlet Engine: Apache Tomcat/7.0.52
2014/10/03 0:04:56 org.apache.tomcat.websocket.server.WsSci onStartup
情報: JSR 356 WebSocket (Java WebSocket 1.0) support is not available when running on Java 6. To suppress this message, run Tomcat on Java 7, remove the WebSocket JARs from $CATALINA_HOME/lib or add the WebSocketJARs to the tomcat.util.scan.DefaultJarScanner.jarsToSkip property in $CATALINA_BASE/conf/catalina.properties. Note that the deprecated Tomcat 7 WebSocket API will be available. 
2014/10/03 0:04:57 org.apache.catalina.core.ApplicationContext log
情報: No Spring WebApplicationInitializer types detected on classpath
2014/10/03 0:04:57 org.apache.catalina.core.ApplicationContext log
情報: Initializing Spring root WebApplicationContext
INFO : org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization started
INFO : org.springframework.web.context.support.XmlWebApplicationContext - Refreshing Root WebApplicationContext: startup date [Fri Oct 03 00:04:57 JST 2014]; root of context hierarchy
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from ServletContext resource [/WEB-INF/spring/root-context.xml]
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@3fb7edd3: defining beans []; root of factory hierarchy
INFO : org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 145 ms
2014/10/03 0:04:57 org.apache.catalina.core.ApplicationContext log
情報: Initializing Spring FrameworkServlet 'appServlet'
INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'appServlet': initialization started
INFO : org.springframework.web.context.support.XmlWebApplicationContext - Refreshing WebApplicationContext for namespace 'appServlet-servlet': startup date [Fri Oct 03 00:04:57 JST 2014]; parent: Root WebApplicationContext
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from ServletContext resource [/WEB-INF/spring/appServlet/servlet-context.xml]
INFO : org.springframework.context.annotation.ClassPathBeanDefinitionScanner - JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning
INFO : org.springframework.context.annotation.ClassPathBeanDefinitionScanner - JSR-330 'javax.inject.Named' annotation found and supported for component scanning
INFO : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@4413515e: defining beans [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0,org.springframework.format.support.FormattingConversionServiceFactoryBean#0,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#0,org.springframework.web.servlet.handler.MappedInterceptor#0,org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#0,org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver#0,org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver#0,org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,org.springframework.web.servlet.resource.ResourceHttpRequestHandler#0,org.springframework.web.servlet.handler.SimpleUrlHandlerMapping#0,org.springframework.web.servlet.view.InternalResourceViewResolver#0,homeController,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0]; parent: org.springframework.beans.factory.support.DefaultListableBeanFactory@3fb7edd3
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/test_req],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String kikuchi.sample.spring.HomeController.home(java.util.Locale,org.springframework.ui.Model)
INFO : org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapped URL path [/resources/**] onto handler 'org.springframework.web.servlet.resource.ResourceHttpRequestHandler#0'
INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'appServlet': initialization completed in 336 ms
2014/10/03 0:04:57 org.apache.coyote.AbstractProtocol start
情報: Starting ProtocolHandler ["http-bio-8080"]
2014/10/03 0:04:57 org.apache.coyote.AbstractProtocol start
情報: Starting ProtocolHandler ["ajp-bio-8009"]
2014/10/03 0:04:57 org.apache.catalina.startup.Catalina start
情報: Server startup in 1500 ms
WARN : org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/spring/] in DispatcherServlet with name 'appServlet'
INFO : kikuchi.sample.spring.HomeController - Welcome home! The client locale is ja_JP.
2014/10/03 0:05:20 org.apache.jasper.compiler.TldLocationsCache tldScanJar
情報: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.

ただ、何度か他のプロジェクトを作ったり起動・停止を繰り返していたらいつの間にか正常に動くようになってしまいました。
※エラーとなった同じプロジェクトを使用

2014/10/03 0:20:57 org.apache.catalina.core.AprLifecycleListener init
情報: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: E:\dev\pleiades\java\6\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;E:/dev/pleiades/eclipse/jre/bin/server;E:/dev/pleiades/eclipse/jre/bin;E:/dev/pleiades/eclipse/jre/lib/amd64;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Intel\OpenCL SDK\3.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\3.0\bin\x64;C:\Program Files (x86)\Windows Live\Shared;E:\install\VIP Access Client\;E:\dev\TortoiseSVN\bin;.;;E:\dev\pleiades\eclipse;;.
2014/10/03 0:20:57 org.apache.tomcat.util.digester.SetPropertiesRule begin
警告: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:SpringMVC_Sample' did not find a matching property.
2014/10/03 0:20:57 org.apache.coyote.AbstractProtocol init
情報: Initializing ProtocolHandler ["http-bio-8080"]
2014/10/03 0:20:57 org.apache.coyote.AbstractProtocol init
情報: Initializing ProtocolHandler ["ajp-bio-8009"]
2014/10/03 0:20:57 org.apache.catalina.startup.Catalina load
情報: Initialization processed in 317 ms
2014/10/03 0:20:57 org.apache.catalina.core.StandardService startInternal
情報: サービス Catalina を起動します
2014/10/03 0:20:57 org.apache.catalina.core.StandardEngine startInternal
情報: Starting Servlet Engine: Apache Tomcat/7.0.52
2014/10/03 0:20:57 org.apache.tomcat.websocket.server.WsSci onStartup
情報: JSR 356 WebSocket (Java WebSocket 1.0) support is not available when running on Java 6. To suppress this message, run Tomcat on Java 7, remove the WebSocket JARs from $CATALINA_HOME/lib or add the WebSocketJARs to the tomcat.util.scan.DefaultJarScanner.jarsToSkip property in $CATALINA_BASE/conf/catalina.properties. Note that the deprecated Tomcat 7 WebSocket API will be available. 
2014/10/03 0:20:58 org.apache.catalina.core.ApplicationContext log
情報: No Spring WebApplicationInitializer types detected on classpath
2014/10/03 0:20:58 org.apache.catalina.core.ApplicationContext log
情報: Initializing Spring root WebApplicationContext
INFO : org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization started
INFO : org.springframework.web.context.support.XmlWebApplicationContext - Refreshing Root WebApplicationContext: startup date [Fri Oct 03 00:20:58 JST 2014]; root of context hierarchy
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from ServletContext resource [/WEB-INF/spring/root-context.xml]
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@46bb05de: defining beans []; root of factory hierarchy
INFO : org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 150 ms
2014/10/03 0:20:58 org.apache.catalina.core.ApplicationContext log
情報: Initializing Spring FrameworkServlet 'appServlet'
INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'appServlet': initialization started
INFO : org.springframework.web.context.support.XmlWebApplicationContext - Refreshing WebApplicationContext for namespace 'appServlet-servlet': startup date [Fri Oct 03 00:20:58 JST 2014]; parent: Root WebApplicationContext
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from ServletContext resource [/WEB-INF/spring/appServlet/servlet-context.xml]
INFO : org.springframework.context.annotation.ClassPathBeanDefinitionScanner - JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning
INFO : org.springframework.context.annotation.ClassPathBeanDefinitionScanner - JSR-330 'javax.inject.Named' annotation found and supported for component scanning
INFO : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@79b0d33c: defining beans [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0,org.springframework.format.support.FormattingConversionServiceFactoryBean#0,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#0,org.springframework.web.servlet.handler.MappedInterceptor#0,org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#0,org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver#0,org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver#0,org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,org.springframework.web.servlet.resource.ResourceHttpRequestHandler#0,org.springframework.web.servlet.handler.SimpleUrlHandlerMapping#0,org.springframework.web.servlet.view.InternalResourceViewResolver#0,homeController,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0]; parent: org.springframework.beans.factory.support.DefaultListableBeanFactory@46bb05de
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String opentone.kikuch.spring_sample.HomeController.home(java.util.Locale,org.springframework.ui.Model)
INFO : org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapped URL path [/resources/**] onto handler 'org.springframework.web.servlet.resource.ResourceHttpRequestHandler#0'
INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'appServlet': initialization completed in 377 ms
2014/10/03 0:20:58 org.apache.coyote.AbstractProtocol start
情報: Starting ProtocolHandler ["http-bio-8080"]
2014/10/03 0:20:58 org.apache.coyote.AbstractProtocol start
情報: Starting ProtocolHandler ["ajp-bio-8009"]
2014/10/03 0:20:58 org.apache.catalina.startup.Catalina start
情報: Server startup in 1535 ms
INFO : opentone.kikuch.spring_sample.HomeController - Welcome home! The client locale is ja_JP.

ふむ…警告がひとつ出てるのが気になりますが(Line:4)、正常に動く方でも出てるので関係無い?
再現性も無くなってしまったし、結局原因はよく分かりませんでした。
また何か分かったことがあったら記事にしたいと思います。