Pro Spring 5 2장 정리중...
프로 스프링 5(원서)를 사놓고 공부를 거의 못했는데(구입은 2020년), 다시 시간이 좀 있어 하려고 합니다.
2장은 일종의 환경설정이라고 생각합니다.
일단 필자가 원하는 환경은 IntelliJ IDEA에 Gradle(Maven은 언급정도만 함), 그리고 스프링은 5.0.0입니다. 실제 소스코드에서는 5.0.10입니다. 물론 현재는 6.0.6까지 나왔네요...
그리고 책의 소스코드가 좀 수준이 높다보니, 실습은 유튜브 KK JavaTutorials 채널을 이용하기로 했습니다.
https://www.youtube.com/playlist?list=PLzS3AYzXBoj9IBdtgXRSyZEwlU2QV-mGG
먼저 Intellij의 새 프로젝트에서 Gradle을 선택한후(인텔리제이는 프로젝트 생성에 에러가 나지 않네요. 역시 달러를 좀 밀어넣으니...)
build.gradle 환경설정입니다.
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
ext {
//spring libs
springVersion = '5.0.10.RELEASE'
spring = [
context : "org.springframework:spring-context:$springVersion",
]
}
repositories {
mavenCentral()
}
dependencies {
implementation spring.context
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
}
test {
useJUnitPlatform()
}
이렇게 하면 메이븐 처럼 버전을 쉽게 관리할 수 있으며 dependencies가 복잡해 지는 것을 방지할 수 있네요
다음은 Message.java (빈 클래스)
package com.oraclejava.model;
import org.springframework.beans.factory.annotation.Value;
public class Message {
@Value(value = "1001")
private int messageId;
@Value(value = "Hello Sora!")
private String message;
public int getMessageId() {
return messageId;
}
public void setMessageId(int messageId) {
this.messageId = messageId;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public String toString() {
return "Message{" +
"messageId=" + messageId +
", message='" + message + '\'' +
'}';
}
}
@Value 어노테이션을 제외하면 평이한 클래스입니다.
Dependency Injection을 수행하는 컨피그 클래스입니다. Xml에 친숙하신 분들은 xml이라고 생각하시면 될듯 하네요.
package com.oraclejava.config;
import com.oraclejava.model.Message;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MessageConfig {
@Bean
public Message getMessage() {
return new Message();
}
}
테스트 클래스입니다.
package com.oraclejava.client;
import com.oraclejava.config.MessageConfig;
import com.oraclejava.model.Message;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(MessageConfig.class);
Message message = ctx.getBean("getMessage", Message.class);
System.out.println(message);
}
}
error!
오후 10:07:38: 실행 중 ':Test.main()'...
> Task :compileJava
> Task :processResources NO-SOURCE
> Task :classes
> Task :Test.main() FAILED
Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.
You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
See https://docs.gradle.org/7.4/userguide/command_line_interface.html#sec:command_line_warnings
2 actionable tasks: 2 executed
정보: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@2d38eb89: startup date [Sat Mar 18 22:07:43 KST 2023]; root of context hierarchy [토 3월 18 22:07:43 KST 2023]
Exception in thread "main" java.lang.IllegalStateException: Cannot load configuration class: com.oraclejava.config.MessageConfig
at org.springframework.context.annotation.ConfigurationClassPostProcessor.enhanceConfigurationClasses(ConfigurationClassPostProcessor.java:414)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanFactory(ConfigurationClassPostProcessor.java:254)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:282)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:126)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:692)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:530)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:88)
at co m.oraclejava.client.Test.main(Test.java:10)
Caused by: java.lang.ExceptionInInitializerError
at org.springframework.context.annotation.ConfigurationClassEnhancer.newEnhancer(ConfigurationClassEnhancer.java:122)
at org.springframework.context.annotation.ConfigurationClassEnhancer.enhance(ConfigurationClassEnhancer.java:110)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.enhanceConfigurationClasses(ConfigurationClassPostProcessor.java:403)
... 7 more
Caused by: org.springframework.cglib.core.CodeGenerationException: java.lang.reflect.InaccessibleObjectException-->Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @1d251891
at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:464)
at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:336)
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:93)
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:91)
at org.springframework.cglib.core.internal.LoadingCache$2.call(LoadingCache.java:54)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61)
at org.springframework.cglib.core.internal.LoadingCache.get(LoadingCache.java:34)
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:116)
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:291)
at org.springframework.cglib.core.KeyFactory$Generator.create(KeyFactory.java:221)
at org.springframework.cglib.core.KeyFactory.create(KeyFactory.java:174)
at org.springframework.cglib.core.KeyFactory.create(KeyFactory.java:153)
at org.springframework.cglib.proxy.Enhancer.<clinit>(Enhancer.java:73)
... 10 more
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @1d251891
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:199)
at java.base/java.lang.reflect.Method.setAccessible(Method.java:193)
at org.springframework.cglib.core.ReflectUtils$1.run(ReflectUtils.java:61)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
at org.springframework.cglib.core.ReflectUtils.<clinit>(ReflectUtils.java:52)
at org.springframework.cglib.core.KeyFactory$Generator.generateClass(KeyFactory.java:243)
at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:329)
... 22 more
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':Test.main()'.
> Process 'command 'G:/pleiades/2022-09/java/17/bin/java.exe'' finished with non-zero exit value 1
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
* Get more help athttps://help.gradle.org
BUILD FAILED in 4s
오후 10:07:44: 실행이 완료되었습니다 ':Test.main()'.
오늘은 여기까지!!