spring

Pro Spring 5 2장 정리중...

다만사 2023. 3. 18. 21:56

프로 스프링 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()'.

 

오늘은 여기까지!!