자바2007.09.02 16:00

Java enum type은 obfuscate할 때 주의가 필요하다. java.lang.Class.getEnumConstants()에서 reflection으로 해당 enum type의 'values'라는 메서드를 참조하기 때문이다.

예를 들어 net.rb.lab.TestEnum이라는 java enum type이 다음과 같은 소스코드를 가진다고 하자.

package net.rb.lab;

public enum TestEnum {

    ITEM_A,
    ITEM_B;
    
}

이 소스코드를 compile하면 다음과 같은 byte code outline을 확인할 수 있다.

net.rb.lab.TestEnum
Fields:
    ITEM_A
    ITEM_B
    ENUM$VALUES
Methods:
    <clinit>
    <init>
    values
    valueOf

실제 byte code를 decompile해보면 대략 아래와 같은 코드를 유추해낼 수 있다.
(아래 소스코드는 byte code의 구조파악을 위해 기술된 내용이고, Enum 상속 문제때문에 실제 complie은 안된다.)

package net.rb.lab;

public final class TestEnum extends Enum {

    public static final TestEnum ITEM_A;
    public static final TestEnum ITEM_B;
    private static final TestEnum[] ENUM$VALUES;

    static {
        ITEM_A = new TestEnum("ITEM_A", 0);
        ITEM_B = new TestEnum("ITEM_B", 1);
        ENUM$VALUES = new TestEnum[] { ITEM_A, ITEM_B };
    }
    
    private TestEnum(String name, int ordinal) {
        super(name, ordinal);
    }

    public static TestEnum[] values() {
        TestEnum[] newArray = new TestEnum[ENUM$VALUES.length];
        System.arraycopy(ENUM$VALUES, 0, newArray, 0, ENUM$VALUES.length);
        return newArray;
    }

    public static TestEnum valueOf(String name) {
        return (TestEnum) Enum.valueOf(TestEnum.class, name);
    }

}

보시다시피 enum type의 경우, Java compiler에 의해서 다음과 같이 두 메서드가 자동으로 생성된다.

  • public static TestEnum[] values()
  • public static TestEnum valueOf(String)

이 두 메서드가 바로 문제의 녀석들이다. TestEnum.valueOf(String) 호출은 결국 Class.getEnumConstants() 호출을 야기하는데, 만약 values() 메서드가 obfuscate되었다면 Class.getEnumConstants()는 reflection으로 해당 메서드를 찾을 수 없으므로 null을 return, 결국 JVM은 'TestEnum은 enum type이 아닐세'라며 exception을 던져버린다.

Obfuscation의 목적은 decompile시 의미파악을 어렵게 하기 위함인데, Java enum type의 'values'나 'valueOf'같은 메서드는 이미 공개된 내용이므로 obfuscation 목록에서 제외하는게 문제를 예방하는 데 도움이 될 것 같다.

신고
Posted by roguebean
기타2007.08.23 02:31

이런 유남생같은 자식... 골때리네.

신고
Posted by roguebean
개발2007.08.14 03:14
다행입니다. 저의 바램대로 일정은 연기되었습니다. 고생에 대한 격려도 받았구요. 좋지 못한 상황까지 각오하고 있었는데, 정말 다행입니다.

제가 초반에 산정했던 프로젝트 일정은 크게 빗나갔습니다. 거대한 산이 존재하고 있다는 것을 프로젝트가 꽤 진행된 이후에 알아챘기 때문입니다. 만만하게 봤다가 큰 코(?) 다쳤지요. 그 이후에 어떻게든 일정을 맞춰보려고 아둥바둥했었지만 역부족이었습니다. 결국 보고는 늦어졌고, 일정에 대한 압박을 느껴 고민 아닌 고민을 했었네요. 물론 관리자와 개발자, 그리고 소프트웨어에 대한 제 생각에는 변화가 없습니다만, 우려했던 현실은 다행히도 해피하게 변했네요.

오늘 좀 더 현실적인 일정을 다시 산정했고, 내일부터 몇 달간은 다시 맘잡고 열근모드 들어가려고 합니다. 후배 개발자가 의욕을 잃지 않도록 격려해주신 분들께 참으로 감사드리고... 당분간 블로그 관리는 좀 소홀해지겠지만, 연말쯤엔 '문제의 작품'을 소개드릴까 하오니, 사알짝 기대바랍니다.

신고
Posted by roguebean
TAG 개발자

티스토리 툴바