<openjpa-2.1.1-r422266:1148538 nonfatal user error> org.apache.openjpa.persistence.ArgumentException: Attempt to cast instance "...EntityItem@bbef5e8" to PersistenceCapable failed.  Ensure that it has been enhanced.

FailedObject: ...EntityItem@bbef5e8

at org.apache.openjpa.kernel.BrokerImpl.assertPersistenceCapable(BrokerImpl.java:4631)

at org.apache.openjpa.kernel.BrokerImpl.persistInternal(BrokerImpl.java:2610)

at org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2555)

at org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2538)

at org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2442)

at org.apache.openjpa.kernel.DelegatingBroker.persist(DelegatingBroker.java:1077)

at org.apache.openjpa.persistence.EntityManagerImpl.persist(EntityManagerImpl.java:715)

...

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:597)

at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)

at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)

at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)

at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)

at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)

at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)

at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)

at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)

at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)

at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)

at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)

at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)

at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)

at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)

at org.junit.runners.ParentRunner.run(ParentRunner.java:236)

at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)

at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)



[해결책]

persistence.xml 에 Item들을 추가하세요.

저작자 표시
Posted by 허니몬


Why? 왜 우분투에서 안드로이드 앱 개발을 해야할까?
    1. 윈도우 보다는 안드로이드 개발하기가 편하다.
      이유 : 윈도우에서 안드로이드폰을 테스트하기 위해서는 USB 드라이버를 제조사별로 설치해야 한다.
        -> 우분투에서는 android용 rule.set만 설정해주면 된다.
    2. 무료로 사용할 수 있는 안정적인 리눅스 운영체제이다.
    3. 개발 중에 필요한 서버테스트 환경 등을 손쉽게 구축할 수 있다.



  적어도 안드로이드 앱 개발자에게는 윈도우보다는 나은 환경을 제공한다(맥북에서 써보니까 맥북도 괜찮다. 하지만, 맥북을 사야한다. 우분투는 지금 쓰는 노트북의 운영체제를 밀고 설치하면 된다).
  우분투에서 안드로이드 앱 개발환경을 구축하기는 쉽다.


1. JDK 설치하기
    1.1. JDK 설치 여부 확인
        - honeymon$ java -version
            = 설치되어 있는 경우 : 2.1.로 넘어가자.
            = 설치되어 있지 않은 경우 : 1.2.로 넘어가자.
    1.2. JDK 설치하기
        - JDK 중 하나를 선택하자.
            = OpenJDK(참조하는 라이브러리에서 오류가 발생한다고 합니다. 다른 분들은 이걸 비추.)
            = SunJDK(많은 분들은 이걸 추천합니다.)
            = IBMJDK 듣보잡!
        - JDK를 설치하기
            = sudo apt-get install sun-6-jdk
            = 설치 완료 확인 : java -version
2. Android SDK 설치하기(ADK -> Android SDK로 변경)
    2.1. 구글 안드로이드 개발 사이트 : http://developer.android.com/index.html
        - 우분투용 Android SDK를 다운로드 받는다
            = Android SDK url : http://developer.android.com/sdk/index.html
            ** i386이라고 되어있지만 아키텍쳐(32bit/64bit)는 크게 신경쓰지 않아도 된다.
        - Android SDK를 지정한 위치에 푼다.
            = honeymon : /home/honeymon/Dev/android-sdk 에 설치함
    2.2. Android SDK가 설치된 경로(PATH)를 .bashrc 에서 설정해준다.
        - 설정 이유 : adb, ddms와 같은 안드로이드를 다루는데 필요한 커맨드를 실행할 수 있도록 해주는 것이다.
        - Tip. 윈도우에서는 1개의 경로가 끝나면 끝에 ;(세미콜론)을 붙이지만, 유닉스와 리눅스에서는 :(콜론)을 사용한다.
          = 윈도우 사용자가 유닉스나 리눅스 환경에서 낯설어하는 부분 중 하나다. 윈도우가 유닉스를 따라한 것이다. 모든 운영체제의 시작은 유닉스였다고 보면 된다.

설정방법 :
  .bashrc 제일 마지막 문장에 PATH 추가

ANDROID_PATH=/home/honeymon/Dev/android-sdk
PATH=$PATH:$ANDROID_PATH/bin

    2.3. Android SDK 경로설정이 완료되었는지 확인한다.
        - adb help
3. Eclipse 설치하기
    3.1. Eclipse DownLoad site : http://www.eclipse.org/downloads/
        - Eclipse IDE for Java Developers 가 안드로이드 앱 개발에는 더 적합해 보인다.
        - 내가 처음에 배울 때는 Eclipse classic 을 추천받았었는데...
    3.2. Eclipse의 압축을 푼다.
    3.3. eclipse.ini 환경을 설정한다.
        - 개발에 적합한 것들과 설정했을 때 관련이 있는 것을 알려준다.
    3.4. eclipse를 설치한다.
4. ADT 플러그인 설치하기
    - 참고 사이트 : http://developer.android.com/sdk/eclipse-adt.html
    4.1. eclipse adt update site 추가 : https://dl-ssl.google.com/android/eclipse/
    4.2. Update 목록에 나온 플러그인을 선택하고 설치한다. 설치 완료 후 이클립스 재시작
    4.3. android Manager에서 ADK의 위치를 설정한다.
    4.4. 개발하려고하는 android 버전의 라이브러리를 확인한다.
        - 다운로드 속도가 느린 편이므로 마음의 여유를 가지고 임하자.
    4.5. 라이브러리 다운로드가 완료된 후 이클립스를 다시 시작한다.
5. ADT 설치확인
    5.1. Android manager를 선택한다.
    5.2. Android Emulator를 추가한다.
    5.3. Android Emulator를 실행한다.
    5.4. DDMS perspective를 선택하여 화면전환 후 5.3.에서 실행한 에뮬레이터가 인식되는지 확인한다.
    5.5. 가볍게 화면을 캡쳐해본다.
6. Android Project 생성하기(맛뵈기)
    6.1. Android Project 추가
    6.2. 실행하기
        - Android Application 선택 -> 수행
    6.3. 5.3.에서 실행한 Emulator에서 실행되는지 확인하기
        - Emulator가 동작하는데 걸리는 시간은 실제 안드로이드가 실행되는 시간보다 오래걸린다.
        - CPU의 성능에 따라서 그 차이가 제법 난다.
        - Emulator보다는 넥서스, 넥서스S, 넥서스 프라임과 같은 레퍼런스폰을 개발기기로 연결해서 테스트하는 것이 좋다.
    6.4. 실행시킨 에뮬레이터가 에뮬레이터에 보이면 정상적인 빌드 및 설치가 완료된 것이다.
7. 안드로이드 개발 Tip
    7.1. Java에 대한 공부는 꾸준하게 한다.
    7.2. 커뮤니티 활동을 한다.
    7.2. 로그(Log)를 잘 이용해서 동작을 체크하자.
        - 디버그(Debug)모드를 자주 이용하면 동작을 한눈에 확인하기 어렵다.
        - 기록(로그)을 세밀하게 남겨서 확인하는 습관을 가지자.
    7.3. Android Reference를 꼼꼼히 읽어두자.
        - 어느 개발서적보다 낫다.
        - 개발서적들은 대부분 저자가 자세히 모르는 내용은 얼버무리게 된다.

     



P.S. 안드로이드 개발용 rule.set 설정하기

저작자 표시
Posted by 허니몬

API 참고 URL : http://download.oracle.com/javase/6/docs/api/java/lang/Class.html

   Class는 JVM(Java Virtual Machine)에서 정의된 클래스로 자동 생성해준다. 자바에서 사용하는 모든 클래스에 존재하는 한다. ㅡ_-)>

처음에는 내가 원하는 기능을 만들기 위해, 내가 할 수 있는 것들을 총동원해서(총동원해도 다른 이들보다 역량이 부족하니 턱없이 완성도가 낮은) 만들려고 했었다. 하지만, 요즘 들어 꺠닫게 되는 것이지만 '내가 필요로 하는 것들은 이미 누군가에 의해 만들어져 있다' 라는 경험을 자주 접하고 있다. 인터넷 검색만 제대로 해도 내가 원하는 기능을 '내가 할 수 있는 방법'보다 훨씬 깔끔하고 간결하게 표현한 것들을 많이 찾아볼 수가 있다.


최근 진행하고 있는 프로젝트에서도 '오픈 소스'로 제공하고 있는 다양한 기능들을 활용하여 만족스런 성과를 거두고 있다(아는 만큼 보인다. '오픈소스'도 마찬찬가지다. 아는 만큼 보인다. 제대로 소스와 언어를 이해하는 사람에게는 잘 보이는 것 같다. 나는 아직 안보여!!).

  '오픈소스' 라고 무턱대고 가져다 쓰다보면 나중에 고생할 수가 있다. 우리 수석님이 강조하고 강조하시는 부분이다.



어쨌든!

'객체에 있는 필드명을 이용해서 정보를 가져올 수 있지 않을까?'

라는 기대를 하면서 인터넷 검색을 하다보니

'왠걸?'

이미 JDK에 기본적으로 있는 java.lang.Class 에서 필요한 부분들을 제공하고 있었다. 우선은 간단하게 어떻게 동작하는지 알아볼겸 테스트 케이스를 작성해봤다. 어떻게 정보를 가져올지 찔러본달까?


package javastudy.clazz;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

import java.lang.reflect.Field;

import org.junit.Before;
import org.junit.Test;

public class ClassTest {

    private TestMakeClass makeClass;
    private String FIELD_NAME = "fieldName";
    private String FIELD_ATTRIBUTE = "filedAttribute";
    private String MAKE_VALUE = "testMakeValue";
    private String MAKE_ATTRIBUTE = "string";

    @Before
    public void setUp() {
        makeClass = new TestMakeClass();
        makeClass.setFieldName(MAKE_VALUE);
        makeClass.setFieldAttribute(MAKE_ATTRIBUTE);
    }

    /**
     * private 접근제어 선언이 되어 있는 경우,
     * field.setAccessible(true) 선언을 해주면 접근이 가능하다. 
     */
    @Test
    public void testClassGetPrivateField() {
        
        Field field = null;
        try {
            field = makeClass.getClass().getDeclaredField(FIELD_NAME);
            field.setAccessible(true);
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

        String fieldNameValue = null;
        try {
            fieldNameValue = (String) field.get(makeClass);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        assertThat(fieldNameValue, is(makeClass.getFieldName()));
    }
    
    /**
     * private 선언된 필드 정보를 가져오려고 하면 IllegalAccessExceptino이 발생함.
     * 
     * @throws SecurityException
     * @throws NoSuchFieldException
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     */
    @Test(expected=IllegalAccessException.class)
    public void testClassGetPrivateFieldThrowsEception() throws SecurityException,
    NoSuchFieldException, IllegalArgumentException,
    IllegalAccessException {
        
        Field field = makeClass.getClass().getDeclaredField(FIELD_NAME);
        
        String fieldNameValue = (String) field.get(makeClass);
        assertThat(fieldNameValue, is(makeClass.getFieldName()));
    }
    
    @Test
    public void testClassGetPublicField() throws SecurityException,
    NoSuchFieldException, IllegalArgumentException,
    IllegalAccessException {
        
        Field field = makeClass.getClass().getDeclaredField(FIELD_ATTRIBUTE);
        
        String fieldAttribute = (String) field.get(makeClass);
        assertThat(fieldAttribute, is(makeClass.getFieldAttribute()));
    }
    
    @Test
    public void testClassGetFileds() throws IllegalArgumentException, IllegalAccessException {
        Field[] fields = makeClass.getClass().getFields();
        System.out.println("fields size is[" +fields.length+ "]");
        
        for(Field field : fields) {
            //public 선언되어 있는 필드 정보만 나타난다. 
            String fieldValue = (String) field.get(makeClass);
            System.out.println(fieldValue);
            
        }
    }

    public class TestMakeClass {
        private String fieldName;
        public String fieldAttribute;

        public String getFieldName() {
            return fieldName;
        }

        public void setFieldName(String fieldName) {
            this.fieldName = fieldName;
        }

        public String getFieldAttribute() {
            return fieldAttribute;
        }

        public void setFieldAttribute(String fieldAttribute) {
            this.fieldAttribute = fieldAttribute;
        }

    }
}

이렇게 해서 fieldName을 이용해서 객체의 필드정보를 뽑아내고, 그 필드정보에서 원하는 정보를 가져오는 방법을 익혀봤다.

객체의 필드를 다루기 위해서 숙지해둬야할 것은,  접근하려고 하는 필드의 '접근제어'에 대한 선언이 어떻게 되어있는지 알고 있어야 한다는 것이다.

처음에는


  '뭐야? 이렇게 필드값을 빼낼 수 있으면 캡슐화를 할 이유가 없잖아?'


하고 생각했지만, 테스트 케이스를 작성하면서


  '아, 그 객체 안에 있는 필드명을 모르면 예외만 보겠구나.'


라고 생각하면서 테스트 케이스를 작성해보다가


  '아, 이걸 XML 등에서 정의해놓고 이 xml에서 정보를 가져와서 요렇게 해서 저렇게 할 수 있곘는데?'


라는 '내가 찾던 해결책'을 찾았다.

  이 부분에 대해서는 나중에 공개하도록 하겠다. ^^; 오늘은 여기

저작자 표시
Posted by 허니몬

관련 사이트 : http://simple.sourceforge.net/home.php


자바를 위한 XML 직렬화처리 및 설정을 해주는 높은 성능의 프레임워크다.

- Simple framework with powerful capabilities

- Can handle cycles in the object graph

- It requires absolutely no configuration

- Extremely rapid development with XML

- Converts to and from human editable XML

- Contains an XML templating system


위의 특징을 가지고 있는 프레임워크다. 자세한 내용은 사이트에 가서 확인하기 바란다.

아래 튜토리얼을 확인하기 바란다.

tutorial : http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php



간단한 예제코드

1. 먼저 Simple framework를 다운로드 받는다.

< Example.java >

  
package javastudy.simplexml;

import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;

@Root
public class Example {
    
    @Element
    private String text;
    
    @Attribute
    private int index;

    public Example() {
        super();
    }

    public Example(String text, int index) {
        super();
        this.text = text;
        this.index = index;
    }

    public String getText() {
        return text;
    }

    public int getIndex() {
        return index;
    }
    
}

<SimpleXmlTest.java> 테스트 코드

  
package javastudy.simplexml;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

import java.io.File;

import org.junit.Test;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;

/**
 * simple Xml serialization 프레임워크를 이용하여 객체를 XML로 변환처리 테스트
 * @author 허니몬
 * 
 * 고려사항 : 
 *  1. Java 객체를 우선 정의해줘야한다.
 */
public class SimpleXmlTest {

    /**
     * Example 클래스의 구조를 example.xml으로 변환하여 xml파일을 생성한다.
     * 이때, 객체 안에 담겨있는 데이터는 @Attribute @Element 애노테이션에 
     * 의해 xml의 attribute와 element로 정의된다. 
     */
    @Test
    public void simpleObjectToXmlTest() {
        Serializer serializer = new Persister();
        Example example = new Example("Example message", 123);
        File result = new File("example.xml");
        
        try {
            serializer.write(example, result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    @Test
    public void simpleXmlToObjectTest() {
        Serializer serializer = new Persister();
        File source = new File("example.xml");
        
        Example example = null;
        try {
            example = serializer.read(Example.class, source);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        assertThat(example.getText(), is("Example message"));
        assertThat(example.getIndex(), is(123));
    }
}


<example.xml> 위의 코드에서 생성된 xml

  

   Example message


의 형태를 띄게 된다. 그 이외의 상세한 내용에 대해서는...

차근차근 해보도록 하자. 요즘 머리에 주입되는 정보들을 처리하느라 힘들다.




사용용도 : 객체(Java source)를 뼈대로 해서 xml파일을 생성하려고 할 때 사용할 수 있을 것이며,

이렇게 생성된 XML에 담긴 정보를 객체에 주입할여 인스턴스를 생성할 수 있을 것이다.


저작자 표시
Posted by 허니몬

  이전에 코드에 임포트한 패키지들을 정리하는 실장님을 보면서 

  '왜 임포트된 패키지를 .* 으로 정리하는건가요?' 

라고 물었다가 답을 들었던 기억이 흐릿해질 때쯤, 이 책을 읽다보니 나오기에 그 기록을 남긴다.

도메인주도설계소프트웨어의복잡성을다루는지혜
카테고리 컴퓨터/IT > 네트워크/보안
지은이 에릭 에반스 (위키북스, 2011년)
상세보기

자바에서는 의존성에 해당하는 임포트 구문(import)을 반드시 개별 클래스에 선언해야 한다. 모델링하는 사람들은 아마 패키지를 다른 패키지에 대한 의존성으로 생각하겠지만, 자바에서는 꼭 그렇지만도 않다.
널리 통용되는 코딩 관례에서는 개별 클래스에 대해 임포트 구문을 작성할 것을 권장하므로 코드는 아래와 같이 작성할 것이다.

import packageB.ClassB1;
import packageB.ClassB2;
import packageB.ClassB3;
import packageC.ClassC1;
import packageC.ClassC2;
import packageC.ClassC3;
...
아쉽게도 자바에서는 개별 클래스에다 임포트할 수밖에 없지만 적어도 한 번에 전체 패키지를 임포트할 수는 있다. 이렇게 하면 패키지명을 일제히 변경하는 노력도 줄어들면서 패키지가 대단히 응집력 있는 단위라는 의도가 반영되기도 한다.

import packageB.*;
import packageC.*;


사실 이 기법은 두 가지 척도(패키지에 의존하는 클래스)를 혼용한다는 것을 의미하지만 앞서 나온 클래스 목록을 나열한 것 이상, 즉 특정 Module에 대한 의존성이 만들어진다는 의도를 전해주기도 한다.


Racing Stars
Racing Stars by Andrew Stawarz 저작자 표시변경 금지


자바에서는 패키지단위로 클래스를 작성하고 관리하지만, 이것을 실제로 모듈화하여 관리하지는 않는다. 서로다른 모듈이라 하더라도, 사용할 때에는 실제적으로 내부적인 동일한 경로의 선상에 놓이게 된다. 이때문에 이클립스를 비롯한 IDE 에서는 관례적으로 임포트되는 클래스의 패키지 경로를 명시하는 형태로 나타난다. 

실제로 임포트 되는 것은 패키지내에 클래스들이겠지만, 

import pacakges.*;

문을 통해서 해당하는 패키지가 응집력있게 사용되는 것이라는 설명을 명시화할 수가 있다.


저작자 표시
Posted by 허니몬
이전버튼 1 2 3 4 5 ... 10 이전버튼