복붙노트

[SPRING] 커맨드 라인에서 -javaagent를 사용하지 않고 Spring과 Tomcat으로 로딩 타임을 설정하는 법

SPRING

커맨드 라인에서 -javaagent를 사용하지 않고 Spring과 Tomcat으로 로딩 타임을 설정하는 법

나는 Spring 3.2.9, Tomcat 6.0.44를 사용하고있다.

Tomcat에 배치 될 때 로딩 시간 짜기를 위해 내 응용 프로그램의 스프링 계측 공급자 (예 : spring-instrumentation.jar)를 구성하려고합니다.

나는 사용하지 말아야한다. "-javaagent : /path/path/spring-instrument.jar"명령 행에서 구성을 수행하십시오.

나는 애플리케이션의 Tomcat 설정의 요소 (Tomcat의 server.xml 또는 웹 애플리케이션의 context.xml)를 수정하여 Spring 도구를 구성 할 수 있다고 읽었다. 적절한 요소를 server.xml에 추가하면 내 응용 프로그램이 Spring의 계측 공급자와 함께 실행되도록 올바르게 구성됩니다. context.xml (아래 참조)에 추가해도 작동하지 않습니다.

META-INF / aop.xml 파일은 다음과 같습니다.

    <aspectj>
        <weaver options="-verbose -showWeaveInfo -debug">
            <include within="com.mv.xx.services..*"/>
            <exclude within="com.mv.xx.aop..*"/>
        </weaver>
        <aspects>
            <aspect name="com.mv.xx.aop.MyAspect"/>
        </aspects>
    </aspectj>

또한 Spring context config에 이것을 추가하여 로딩 타임 weaving을 사용하도록 지정합니다.

 <context:load-time-weaver />

그리고이 항아리를 내 응용 프로그램의 classpath에 추가합니다. spring-instrument-tomcat.jar

내가해온 것 :

Tomcat을 시작할 때, 다음과 같이 -javaagent 매개 변수를 사용하여 명령 줄에서 spring-instrument.jar의 위치를 ​​식별하면 :

-javaagent:/path/path2/spring-instrument-3.2.9.RELEASE.jar

모든 것이 잘 작동합니다.

다음으로 커맨드 라인에서 "-javaagent : /path/path2/spring-instrument-3.2.9.RELEASE.jar"를 삭제했습니다. Tomcat의 server.xml 파일 ($ CATALINE_HOME / conf에 있음)에서 다음과 같이 요소에 요소를 추가했습니다.

<Context path="/myApp" docBase="myApp">
    <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
</Context>

이 구성으로 모든 것이 올바르게 작동합니다. 그러나 나는 server.xml을 제어 할 수 없으므로 Tomcat의 server.xml을 수정하지 말아야한다는 요구 사항이 있습니다. DevOps는 그것을 수정하기를 주저합니다.

다음으로 Tomcat의 server.xml에서 요소를 제거했다. 스프링 문서에 따르면 /META-INF/context.xml을 webapp에 추가하고 Tomcat의 server.xml에 있던 요소를 context.xml에 넣을 수 있습니다.

        <Context>
            <Context path="/myApp" docBase="myApp">
                <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
            </Context>
        </Context>

그러나 Tomcat을 재시작하면 로그에 다음과 같은 오류 메시지가 나타납니다.

    SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.context.weaving.AspectJWeavingEnabler#0': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loadTimeWeaver': Initialization of bean failed; nested exception is java.lang.IllegalStateException: ClassLoader [org.apache.catalina.loader.WebappClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar

주위를 파고 들자, 다음과 같이 스프링 설정에서 요소를 수정하도록 제안한 내용을 읽었습니다.

        <context:load-time-weaver weaver-class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />

그리고 InstrumentationLoadTimeWeaver.class를 포함하는 항아리를 클래스 패스에 추가하십시오.

그러나 그렇게하면 로그에 다음과 같은 오류 메시지가 나타납니다.

        SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
        java.lang.IllegalStateException: Must start with Java agent to use InstrumentationLoadTimeWeaver. See Spring documentation.
    etc....

누구든지 명령 줄에서 -javaagent를 사용하지 않고 server.xml을 수정하지 않고 Spring 및 Tomcat으로로드 시간 짜기를 설정하는 방법을 설명 할 수 있습니까?

해결법

  1. ==============================

    1.이것은 내가 언급 한 예외를 제거하기 위해 사용하는 코드입니다. 기본적으로 LoadTimeWeavingConfigurer를 구현하고 getLoadTimeWeaver () 메서드를 재정의해야합니다.

    이것은 내가 언급 한 예외를 제거하기 위해 사용하는 코드입니다. 기본적으로 LoadTimeWeavingConfigurer를 구현하고 getLoadTimeWeaver () 메서드를 재정의해야합니다.

    @Configuration
    @ComponentScan(basePackages = "org.myproject")
    @EnableAspectJAutoProxy
    @EnableSpringConfigured
    @EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.AUTODETECT)
    public class Config implements LoadTimeWeavingConfigurer {
    
        @Override
        public LoadTimeWeaver getLoadTimeWeaver() {
            return new ReflectiveLoadTimeWeaver();
        }
    
        @Bean
        public InstrumentationLoadTimeWeaver loadTimeWeaver()  throws Throwable {
            InstrumentationLoadTimeWeaver loadTimeWeaver = new InstrumentationLoadTimeWeaver();
            return loadTimeWeaver;
        }
    
    }
    
  2. ==============================

    2.나는 이것을 수행하기 위해 invesdwin-instrument를 사용했다. 로드 시간 짜기 계측을 동적으로 사용할 수 있으므로 javaagent를 사용할 필요가 없습니다.

    나는 이것을 수행하기 위해 invesdwin-instrument를 사용했다. 로드 시간 짜기 계측을 동적으로 사용할 수 있으므로 javaagent를 사용할 필요가 없습니다.

    Tomcat 8.5에서 작동하게하려면 약간의 노력이 필요했습니다. 그러나 마지막으로 스프링 부트와 함께이 구성을 사용하여 작업합니다.

    @SpringBootApplication
    @EnableLoadTimeWeaving // instead of @ImportResource(locations = "classpath:/META-INF/ctx.spring.weaving.xml")
    public class MySpringBootApplication {
        public static void main(final String[] args) {
            DynamicInstrumentationLoader.waitForInitialized(); //dynamically attach java agent to jvm if not already present
            DynamicInstrumentationLoader.initLoadTimeWeavingContext(); //weave all classes before they are loaded as beans
            SpringApplication.run(MySpringBootApplication.class, args); //start application, load some classes
        }
    }
    

    이전 버전의 Tomcat에서도 작동해야합니다.

    문안 인사

  3. ==============================

    3.

    https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Performance/Weaving/Static_Weaving
    

    위의 링크에서 Maven 플러그인을 사용해보십시오. 효과가있다.

  4. from https://stackoverflow.com/questions/35993888/how-to-setup-load-time-weaving-with-spring-and-tomcat-without-using-the-javaage by cc-by-sa and MIT license