Spring SecurityでWebSecurityConfigurerAdapterがみつからない【Kotlinサーバーサイドプログラミング実践開発】

# はじめに

以下の書籍を読んでいたところ躓いた内容についてまとめます

https://www.amazon.co.jp/Kotlin-%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%82%B5%E3%82%A4%E3%83%89%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E5%AE%9F%E8%B7%B5%E9%96%8B%E7%99%BA-%E7%AB%B9%E7%AB%AF-%E5%B0%9A%E4%BA%BA/dp/4297118599/ref=sr_1_2?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=U9X4NA5QCUE7&keywords=kotlin&qid=1673079919&sprefix=kotli%2Caps%2C190&sr=8-2

# 問題

書籍のP187の以下の行でIntellijがモジュールが見つからないとエラーを出しました

```kotlin:SecurityConfig.kt
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
```

# 解決方法

https://www.docswell.com/s/MasatoshiTada/KGVY9K-spring-security-intro#p16

Spring Security 6系で廃止されていました
`spring-boot-starter-security`で`spring-security-config`を入れると自動的に最新の6系が入ってしまうので見つからないことがわかりました

そこで以下のように`spring security`のみバージョン指定で入れました

```
	implementation("org.springframework.boot:spring-boot-starter-security")
	implementation("org.springframework.security:spring-security-config:5.6.10")
```

すると`WebSecurityConfigurerAdapter`がインポートできました


# 別の問題

実行はできるようになったものの、これで実行すると以下のエラーが発生して書籍は進められませんでした

```
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.0.1)

2023-01-07T17:10:37.352+09:00  INFO 34087 --- [           main] c.book.manager.BookManagerApplicationKt  : Starting BookManagerApplicationKt using Java 18.0.2 with PID 34087 (/home/watanabejin/workspace/book-manager/build/classes/kotlin/main started by watanabejin in /home/watanabejin/workspace/book-manager)
2023-01-07T17:10:37.356+09:00  INFO 34087 --- [           main] c.book.manager.BookManagerApplicationKt  : No active profile set, falling back to 1 default profile: "default"
2023-01-07T17:10:38.071+09:00 ERROR 34087 --- [           main] o.s.boot.SpringApplication               : Application run failed

java.lang.IllegalStateException: Error processing condition on org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration.propertySourcesPlaceholderConfigurer
	at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60) ~[spring-boot-autoconfigure-3.0.1.jar:3.0.1]
	at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108) ~[spring-context-6.0.3.jar:6.0.3]
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:183) ~[spring-context-6.0.3.jar:6.0.3]
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:144) ~[spring-context-6.0.3.jar:6.0.3]
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:120) ~[spring-context-6.0.3.jar:6.0.3]
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:410) ~[spring-context-6.0.3.jar:6.0.3]
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:283) ~[spring-context-6.0.3.jar:6.0.3]
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:344) ~[spring-context-6.0.3.jar:6.0.3]
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:115) ~[spring-context-6.0.3.jar:6.0.3]
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:745) ~[spring-context-6.0.3.jar:6.0.3]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:565) ~[spring-context-6.0.3.jar:6.0.3]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.0.1.jar:3.0.1]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730) ~[spring-boot-3.0.1.jar:3.0.1]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432) ~[spring-boot-3.0.1.jar:3.0.1]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-3.0.1.jar:3.0.1]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302) ~[spring-boot-3.0.1.jar:3.0.1]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291) ~[spring-boot-3.0.1.jar:3.0.1]
	at com.book.manager.BookManagerApplicationKt.main(BookManagerApplication.kt:13) ~[main/:na]
Caused by: java.lang.IllegalStateException: Failed to introspect Class [org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration] from ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader@251a69d7]
	at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:483) ~[spring-core-6.0.3.jar:6.0.3]
	at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:360) ~[spring-core-6.0.3.jar:6.0.3]
	at org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:417) ~[spring-core-6.0.3.jar:6.0.3]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.lambda$getTypeForFactoryMethod$1(AbstractAutowireCapableBeanFactory.java:749) ~[spring-beans-6.0.3.jar:6.0.3]
	at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708) ~[na:na]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:748) ~[spring-beans-6.0.3.jar:6.0.3]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:681) ~[spring-beans-6.0.3.jar:6.0.3]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:652) ~[spring-beans-6.0.3.jar:6.0.3]
	at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1632) ~[spring-beans-6.0.3.jar:6.0.3]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:559) ~[spring-beans-6.0.3.jar:6.0.3]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:531) ~[spring-beans-6.0.3.jar:6.0.3]
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition.collectBeanNamesForType(OnBeanCondition.java:250) ~[spring-boot-autoconfigure-3.0.1.jar:3.0.1]
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:243) ~[spring-boot-autoconfigure-3.0.1.jar:3.0.1]
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:233) ~[spring-boot-autoconfigure-3.0.1.jar:3.0.1]
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchingBeans(OnBeanCondition.java:181) ~[spring-boot-autoconfigure-3.0.1.jar:3.0.1]
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchOutcome(OnBeanCondition.java:156) ~[spring-boot-autoconfigure-3.0.1.jar:3.0.1]
	at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47) ~[spring-boot-autoconfigure-3.0.1.jar:3.0.1]
	... 17 common frames omitted
Caused by: java.lang.NoClassDefFoundError: javax/servlet/Filter
	at java.base/java.lang.Class.getDeclaredMethods0(Native Method) ~[na:na]
	at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3434) ~[na:na]
	at java.base/java.lang.Class.getDeclaredMethods(Class.java:2536) ~[na:na]
	at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:465) ~[spring-core-6.0.3.jar:6.0.3]
	... 33 common frames omitted
Caused by: java.lang.ClassNotFoundException: javax.servlet.Filter
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[na:na]
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]
	... 37 common frames omitted
```

ここで書籍は止まっています
最近になっていろいろ変わったようで、そもそも廃止された方法で設定が書かれているため新たな方法で設定を書く必要がありそうですが、そこは学習のスコープ外として7章は飛ばすことにしました

誰か7章をやられた方がいたら設定を教えていただきたいです

# 追記 : spring-securityの設定

spring-securityは2022年12月にバージョン6に変わって設定ファイルの書き方が変わりました
そこで以下のハンズオンで学べるように用意したのでハンズオンを書籍に照らし合わせながら行うと7章も問題なく実行できるようになります

https://zenn.dev/jinwatanabe/articles/c3860019dbf522

# おわりに

この書籍でいろいろつまづき頑張って解決しましたが、さすがにこの設定をすべて書き換えるのは大変すぎて本来学習したいこととずれてしまうため諦める選択肢を取りました

Kotlinの新しいWebアプリケーションを解説した書籍が今年出ることを願います

# 参考

https://www.docswell.com/s/MasatoshiTada/KGVY9K-spring-security-intro#p16

https://mvnrepository.com/artifact/org.springframework.security/spring-security-config