2013-11-27 1 views
1

오픈 소스 라이프 사이클 프레임 워크 API 공급자로서, 내재적 인 방식으로 내재적 인 디자인을 제공하여 라이프 사이클 제공 API로 사용하려고합니다. API 클라이언트에 훨씬 더 많은 편의를 가져다 줄 것입니다.자바 명령 줄에 javaagent 옵션을 지정하지 않고로드 시간 바이트 코드 변환에 대한 해결책이 있습니까?

코어 Java 응용 프로그램과 Java EE 응용 프로그램 모두의 구성을 피할 것으로 예상되지만 실제로는 Java 명령 -javaagent : $ {path} /Lifecycle.jar 옵션을 사용하여 클래스에서 자체 ClassFileTransformer를 사용 가능하게합니다. 로드 시간.

일부 검색 후 일부 확실하지 않은 길 찾기가 발견되었습니다. 우리를 요약하고 안내하기 위해 Java Guy가 필요합니다. 모두 premain VS

  1. agentmain
  2. 같은 바이트 코드 변환을 수행하기 위해 다음과 같은 방법을 가지고 글래스 피쉬의 ByteCodePreprocessor으로 지정 런타임 환경과 intergration :

    public byte[] preprocess(String classname, byte[] classBytes);

내 혼란 약을 방향 :

  1. 핵심 Java 응용 프로그램의 경우 시작 클래스의 main 메서드를 agentmain 솔루션에 맞게 수정할 수있는 것으로 보입니다. 다른 옵션이 있습니까?
  2. 글래스 피시와 같은 JavaEE 컨테이너를 사용하려면 ByteCodePreprocessor를 사용하여 클래스 바이트 코드를 수정할 수 있지만 몇 가지 새로운 클래스를 만들어야하지만 새 클래스 파일을 저장할 위치 나 새로운 ClassLoader를 적용 해, 클래스 파일의 전처리 중에 새롭게 작성한 클래스 파일을로드합니다. 잘

(EntityManager의 인터페이스없이 JPA와 매우 가까운, 대부분 지금은 단지 주석과 CallbackContext 인터페이스와 LifecycleEvent 인터페이스입니다 메타 중심의 스타일을 따를 것이다. BTW 라이프 사이클 API)

+0

해결책으로 답변을 표시했지만 기본적으로 제공되는 [javassist] (http://www.csg.ci.iu-tokyo.ac.jp/~chiba/javassist/)를 살펴볼 수도 있습니다. 클래스 바이트 조작 및 추가 java 문을 클래스, 생성자 및 메소드에 주입합니다. 실제로 그것을 보시려면 [간단한 플러그인 프레임 워크] (https://github.com/RovoMe/PluginApplication/blob/master/PluginFramework/PluginCore/src/main/java/at/rovo/core/)를 살펴보십시오. classloader/InjectionLoaderStrategyDecorator.java) 나는 대학 과정을 위해 썼다. –

답변

2

, 내가 생각할 수있는 유일한 다른 방법은 런타임에 등록 할 수있는 사용자 정의 클래스 로더를 사용하는 것입니다. 이것이 Powermock과 같은 프레임 워크가 얼마나 힘든 일을 하는가입니다. 그러나 이렇게하려면 일부 설정이 필요하지만 프로그래밍 방식으로 수행 할 수 있습니다.

프레임 워크에 엔트리 포인트가 잘 정의되어 있고 모든 코드가 응용 프로그램 내에서 실행되는 한 모든로드 된 클래스를 인스트루먼트 할 수있는 사용자 정의 클래스 로더를 적용 할 수 있습니다.

그러나 이미로드 된 클래스에는 작동하지 않습니다. 부모의 첫 번째 부역을 깨뜨릴 수는 있지만 프레임 워크 외부에서 인스턴스에 대해 ClassCastException을 발생시킬 수 있습니다.)

이렇게하지 않으려면 동일하게 자세한 시스템 클래스 로더를 대체해야합니다. 완전성을 위해, 여기 ClassLoader.getSystemClassLoader의 자바 독의 발췌입니다

이 방법은 먼저 해당 속성의 값을 호출 할 때 시스템 프로퍼티 「java.system.class.loader」가 정의되는 경우, 시스템 클래스 로더로 리턴 될 클래스의 이름이 취해집니다. 클래스는 기본 시스템 클래스 로더를 사용하여로드되며 은 위임 부모로 사용되는 ClassLoader 유형의 단일 매개 변수를 사용하는 공용 생성자를 정의해야합니다. 인스턴스는 이며 기본 시스템 클래스 loader를 매개 변수로하여이 생성자를 사용하여 생성됩니다. 생성 된 클래스 로더는 시스템 클래스 로더 인 으로 정의됩니다.

이 사용자 정의 클래스 로더에서는 계측 클래스를 항상 반환 할 수 있습니다.

difference between agentmain and premain은 실행중인 JVM (via the attach API)에 에이전트를 연결할 때 전자가 호출되는 반면 에이전트는 JVM의 시작시 명령 줄에 에이전트가 지정된 경우 호출됩니다. 런타임에 에이전트를 등록하는 것이 실제로 당신을위한 솔루션 일 수 있습니다. 내가 링크 한 블로그 항목은 그 점에 대해 아주 잘 설명하고 있습니다.

+0

Raphw. 감사합니다. 나는 당신의 대답을 여러 번 아주 조심스럽게 읽었다. 그리고 내가 제공 한 모든 링크를 읽었습니다. 마지막으로 나는 내 문제에 대한 당신의 생각을 가지고 있다고 생각합니다. –

+0

Raphw에게 감사드립니다. 나는 당신의 대답을 여러 번 아주 조심스럽게 읽었다. 그리고 내가 제공 한 모든 링크를 읽었습니다. 마지막으로 나는 내 문제에 대한 당신의 생각을 가지고 있다고 생각합니다. 에이전트 클래스를 동적으로로드하려면 응용 프로그램 클래스를로드하기 전에 일부 코드를 실행해야합니다. 핵심 Java 응용 프로그램의 경우 기본 클래스 만 수정할 수 있습니다. JavaEE 앱의 경우 컨테이너의 라이프 사이클 이벤트를 사용하여 에이전트 jar를로드 할 수 있습니다. 그리고 새로운 인스트루먼트 클래스를 생성하고로드하려면 java.system.class.loader를 사용할 수 있습니다. 답에서 요약 한 두 가지 방법을 사용하는 동안 다른 고려 사항이 있습니까? –

+0

그건 내가 표현하려고했던 것입니다. 응용 프로그램 시작 후 클래스를 계측 할 때 이미로드 된 클래스를 계측하는 것은 거의 불가능합니다. 그러나 프로그램 시작 후 에이전트를 등록 할 수 있습니다 (예 : http://dhruba.name/2010/02/07/creation-dynamic-loading-and-instrumentation-with-javaagents/).이 에이전트는 사용자가 아직로드되지 않은 클래스 프레임 워크에 잘 정의 된 진입 점이있는 경우이 에이전트를 한 번만 등록 할 수 있습니다. (예 : Some'Framework.initialize()') –

관련 문제