달력

52024  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
최근 Spring MVC를 사용하면서 가장 주요하게 사용하는 기능은 두가지입니다.
1. Bean Validation
2. Custom ArgumentResolvers

Bean Validation 의 경우 Spring 3.0 에서 mvc:annotation-driven 을 통해 간단하게 사용할 수 있습니다.
하지만 Custom ArgumentResolvers 를 사용하기 위해 AnnotationMethodHandlerAdapter 를 사용하게 되는 경우 빈 등록 과정에서 중복으로 등록되는 어려움이 발생합니다.

@ 이전설정
<!-- @Controllers의 Formatting, Validation, Conversion -->
<mvc:annotation-driven />
<!-- Controller의 파라미터 처리자(WebArgumentResolver) -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="customArgumentResolvers">
        <list>
            <bean class="openframework.common.utils.GukArgumentResolver" />
        </list>
    </property>       
</bean>

@ 바꾼설정
<!-- Controller의 파라미터 처리자(WebArgumentResolver) -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="customArgumentResolvers">
        <list>
            <bean class="openframework.common.utils.GukArgumentResolver" />
        </list>
    </property>
    <property name="webBindingInitializer">
        <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
            <property name="validator">
                <bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
            </property>
        </bean>
    </property>
</bean>

편리하긴 하나, mvc:annotation-driven 를 제거하고 webBindingInitializer에 validator 를 수동으로 지정했습니다.
그러니 잘 돌아가네요.





Posted by fromm0
|
Spring 프레임워크를 사용함에 있어서 가장 좋은 기능중 하나가 선언적인 트랜잭션 관리를 통해 코드에 트랜잭션 관리를 위한 코드를 하나도 넣지 않아도 된다는 것입니다.
3.0에서는 Spring AOP와 @Transactional 애노테이션을 제공하여 그 기능을 사용할 수 있는데요.

Spring AOP를 사용함에 있어서 발행하는 많은 문제를 해결하기 위해서는 SpringSource Tools Suite(정확히는 Spring IDE의) 의 AOP Extension을 사용해서 시각적으로 확인하는 것이 가장 좋습니다.

@ Spring IDE AOP Extension eclipse plugin


메뉴얼을 볼때 기본 설정은 대략 아래와 같습니다.
조금 다른건 저는 Spring Bean을 인터페이스가 아닌 클래스로 사용하기 때문에 proxy-target-class속성값이 true인 점 정도죠.
그리고 expose-proxy 값을 true로 주었습니다. AOP가 적용되어야 할 메서드 두개중 한군데가 계속 적용이 되길래 테스트 코드를 돌렸더니 JUnit 에러에서 친절하게 저 옵션을 켜달라고 해서 추가했습니다.
AOP가 적용되어야 할 메서드 중 일부만 적용될 경우 테스트 코드를 돌려보시거나 저 설정을 고려해보시면 될듯 합니다.
Spring AOP Extension을 사용하면 아래처럼 설정파일에 아이콘을 pointcut이 작동함으로 시각적으로 보여줍니다.
@ Spring AOP설정


그리고 그 대상 소스에도 함께 표기가 되죠. 즉 이 두 아이콘이 표기되면 설정상에 문제가 없다는 뜻입니다.
@ 대상 코드


근데, 이렇게 하더라도 안되는 경우가 있습니다.
특히 Spring @MVC 를 사용할때인데요. 이 경우 설정파일에서 @Controller 를 컨포넌트 스캔할때 옵션을 확인해보시면 됩니다.
use-default-filters를 false로 설정하시거나, @Service, @Repository를 모두 exclude로 제외하시면 됩니다.

<context:component-scan base-package="com.naver.newsstand.service" use-default-filters="false">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>






Posted by fromm0
|
# 테스트 환경
1. jdk1.6.0_23
2. 프로파일러 : JProfiler v.5.2.4

# 케이스별 테스트 소스와 프로파일링 결과
1. 모델의 setter메서드로 셋팅
public static JaxbMessage validateUrlParam(BindingResult result) {
    if (result.hasErrors()) {
        JaxbMessage message = getDefaultMessage();
        LOGGER.info("바인딩결과 : {} ", result);

        JaxbError error = new JaxbError();
        final String errorCode = result.getFieldErrors().get(0).getDefaultMessage();
        error.setCode(errorCode);
        error.setMsg(ValidationErrorMessageAccessor.getMessages().get(errorCode));

        LOGGER.info("{}", error);

        message.setError(error);
        return message;
    }
    return null;
}


20번 호출에 15,653us 소요됨

2. Spring의 BeanUtils.getPropertyDescriptors() 메서드와 Java의 리플렉션 사용
public M validateUrlParamOld(M message, E error, String service, String type, String version, BindingResult result) {
    if (result.hasErrors()) {
        LOGGER.info("바인딩결과 : {} ", result);

        final String errorCode = result.getFieldErrors().get(0).getDefaultMessage();
        try {
            PropertyDescriptor[] errorPds = BeanUtils.getPropertyDescriptors(error.getClass());
            for (PropertyDescriptor desc : errorPds) {
                if ("code".equals(desc.getName())) {
                    Method setter = desc.getWriteMethod();
                    setter.invoke(error, errorCode);
                }
                if ("msg".equals(desc.getName())) {
                    Method setter = desc.getWriteMethod();
                    setter.invoke(error, ValidationErrorMessageAccessor.getMessages().get(errorCode));
                }
            }

            PropertyDescriptor[] messagePds = BeanUtils.getPropertyDescriptors(message.getClass());
            for (PropertyDescriptor desc : messagePds) {
                if ("error".equals(desc.getName())) {
                    Method setter = desc.getWriteMethod();
                    setter.invoke(message, error);
                }
                if ("service".equals(desc.getName())) {
                    Method setter = desc.getWriteMethod();
                    setter.invoke(message, service);
                }
                if ("type".equals(desc.getName())) {
                    Method setter = desc.getWriteMethod();
                    setter.invoke(message, type);
                }
                if ("version".equals(desc.getName())) {
                    Method setter = desc.getWriteMethod();
                    setter.invoke(message, version);
                }
            }
        } catch (IllegalArgumentException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        }

        return message;
    }
    return null;
}


20번 호출에 21,372us 소요됨

3. Spring의 ReflectionUtils 사용
public M validateUrlParam(M message, E error, String service, String type, String version, BindingResult result) {
    if (result.hasErrors()) {
        LOGGER.info("바인딩결과 : {} ", result);

        final String errorCode = result.getFieldErrors().get(0).getDefaultMessage();
        try {
            ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(error.getClass(), "setCode", String.class), error, errorCode);
            ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(error.getClass(), "setMsg", String.class), error,
                ValidationErrorMessageAccessor.getMessages().get(errorCode));

            ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(message.getClass(), "setError", error.getClass()), message, error);
            ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(message.getClass(), "setService", String.class), message, service);
            ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(message.getClass(), "setType", String.class), message, type);
            ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(message.getClass(), "setVersion", String.class), message, version);
        } catch (IllegalArgumentException e) {
            throw new RuntimeException(e);
        }

        return message;
    }
    return null;
}


20번 호출에 13,008us 소요됨

# 정리
1. 순수하게 JDK의 리플렉션을 사용한 테스트 수치는 없음
2. Spring
ReflectionUtils < 모델 setter 메서드 < Spring의 BeanUtils.getPropertyDescriptors() 메서드와 Java의 리플렉션 순으로 소요시간이 적음
3. 모델 setter 메서드 방식이 가장 빠를 것으로 짐작했으나, 예상과 다른 결과가 나타남. 좀더 테스트가 필요할 것으로 생각됨
Posted by fromm0
|
# 테스트 환경
1. jdk1.6.0_23
2. 프로파일링 옵션 : -Xrunhprof:cpu=samples,file=d:/cpu1.txt,depth=3
runhprof 옵션은 jdk 가 제공하는 기본 프로파일링 기능으로 자세한 내용은 "java -Xrunhprof:help" 명령어를 통해 확인할 수 있음
3. 테스트 항목
- StopWatch 를 사용한 메서드 시작과 종료 직전의 시각을 측정
- runhprof 옵션을 통한 cpu 타임 샘플링

# 테스트 케이스 및 테스트 소스와 소요시간(단위 밀리세컨드)
1. 문자열 연산(O), 10만번, slf4j - 5번 테스트해서 평균 산정
@Test
public void test() {
    StopWatch watch = new StopWatch();
    watch.start();
    for (int i = 0; i < 100000; i++) {
        LOGGER.info("a" + "b" + "c" + "d");
    }
    watch.stop();
    LOGGER.info(String.valueOf(watch.getTotalTimeMillis()));
}

total time, cpu time : 7839, 1170
total time, cpu time : 8288, 1146
total time, cpu time : 8123, 1129
total time, cpu time : 8228, 1180
total time, cpu time : 8093, 1222

2. 문자열 연산(X), 10만번, slf4j - 5번 테스트해서 평균 산정
@Test
public void test() {
    StopWatch watch = new StopWatch();
    watch.start();
    for (int i = 0; i < 100000; i++) {
        LOGGER.info("abcd");
    }
    watch.stop();
    LOGGER.info(String.valueOf(watch.getTotalTimeMillis()));
}

total time, cpu time : 7854, 1132
total time, cpu time : 7920, 1169
total time, cpu time : 8078, 1226
total time, cpu time : 7931, 1153
total time, cpu time : 8072, 1118

# JDK 가 처리하는 문자열 처리 방식이 나뉘네요.
두분이 댓글 달아주신것처럼 추가로 확인해봤습니다. (2011년1월3일 추가)


3. 로그레벨 체크, 10만번, slf4j - 5번 테스트해서 평균 산정
 @Test
public void test() {
    StopWatch watch = new StopWatch();
    watch.start();
    for (int i = 0; i < 100000; i++) {
        if (LOGGER.isInfoEnabled()) {

        }
    }
    watch.stop();
    LOGGER.info(String.valueOf(watch.getTotalTimeMillis()));
}

total time, cpu time : 3, 104
total time, cpu time : 3, 107
total time, cpu time : 4, 103
total time, cpu time : 3, 107
total time, cpu time : 2, 106

4. 로그레벨보다 하위레벨로 로깅(실제로는 찍히지 않는 형태), 10만번, slf4j - 5번 테스트해서 평균 산정
 @Test
public void test() {
    StopWatch watch = new StopWatch();
    watch.start();
    for (int i = 0; i < 100000; i++) {
        LOGGER.debug("abcd");
    }
    watch.stop();
    LOGGER.info(String.valueOf(watch.getTotalTimeMillis()));
}

total time, cpu time : 3, 106
total time, cpu time : 4, 104
total time, cpu time : 3, 105
total time, cpu time : 3, 106
total time, cpu time : 3, 104

5. 문자열 연산(O), 100만번, log4j - 1번 테스트해서 평균 산정
 @Test
public void test() {
    StopWatch watch = new StopWatch();
    watch.start();
    for (int i = 0; i < 1000000; i++) {
        LOGGER.info("a" + "b" + "c" + "d");
    }
    watch.stop();
    LOGGER.info(String.valueOf(watch.getTotalTimeMillis()));
}

total time, cpu time : 74702, 11390

5. 문자열 연산(O), 100만번, slf4j - 1번 테스트해서 평균 산정
 @Test
public void test() {
    StopWatch watch = new StopWatch();
    watch.start();
    for (int i = 0; i < 1000000; i++) {
        LOGGER.info("{}{}{}{}", new Object[] {"a", "b", "c", "d"});
    }
    watch.stop();
    LOGGER.info(String.valueOf(watch.getTotalTimeMillis()));
}

total time, cpu time : 76899, 11532

6. ReflectionToStringBuilder 연산, 10만번, slf4j - 1번 테스트해서 평균 산정
 @Test
public void test() {
    StopWatch watch = new StopWatch();
    watch.start();
    for (int i = 0; i < 100000; i++) {
        LOGGER.debug(ReflectionToStringBuilder.toString(article, ToStringStyle.MULTI_LINE_STYLE));
    }
    watch.stop();
    LOGGER.info(String.valueOf(watch.getTotalTimeMillis()));
}

total time, cpu time : 12985, 2656

# ReflectionToStringBuilder.toString() 처리를 해당 모델 클래스의 toString() 을 오버라이딩하면서 처리하는 것으로 배봤습니다. (2011년1월3일 추가)

# 평균수치(단위 밀리세컨드)
1. 문자열 연산(O), 10만번, slf4j
total time, cpu time : 8114.2, 1169.4

2. 문자열 연산(X), 10만번, slf4j
total time, cpu time : 7971, 1159.6

3. 로그레벨 체크, 10만번, slf4j
total time, cpu time : 3, 105.4

4. 로그레벨보다 하위레벨로 로깅(실제로는 찍히지 않는 형태), 10만번, slf4j
total time, cpu time : 3.2, 105

5. 문자열 연산(O), 100만번, log4j
total time, cpu time : 74702, 11390

5. 문자열 연산(O), 100만번, slf4j
total time, cpu time : 76899, 11532

6. ReflectionToStringBuilder 연산, 10만번, slf4j
total time, cpu time : 12985, 2656

# 정리
- 1, 2번 경우를 볼때, 문자열 연산으로 인한 차이(8114, 7971)가 크지 않은 것 같다.
- 1, 2번 경우는 JDK 컴파일 과정의 최적화 작업으로 성능테스트 결과 차이가 없다.
- Logger로 찍어주는 문자열 자체가 연산에 의해 생성될 경우 LOGGER.isInfoEnabled() 형태로 체크하는 것이 성능상 좋을 수 있다.
- Logger로 찍어주는 문자열 자체가 특별한 연산에 의해 생성되는 경우가 아닐 경우, Logger 자체가 로그 레벨 체크 후 로깅 여부를 판단하는데 LOGGER.isInfoEnabled() 형태로 체크하지 않아도 특별한 성능상의 차이가 발생하지 않을 것으로 보인다.
- 5, 6번 경우를 볼때, log4j와 slf4j의 성능차가 크다고 보기는 어렵다.
- ReflectionToStringBuilder.toString() 처럼 문자열을 생성하는 연산의 비용이 클 경우 LOGGER.isInfoEnabled() 를 사용해서 체크하거나 해당 모델 클래스의 toString을 오버라이드 하고 slf4j 의 파라미터 인자로 처리하면 성능의 이점이 있다.

Posted by fromm0
|
캘린더를 통해 일정을 확인하는 건 좋은데, 이상하게 알림 기능이 약하다 싶다.
이 정도가 아닐듯 한데, 싶어 폰을 이리저리 만지다 보니 설정에 몇가지 설정이 있다.

# 설정위치
캘린더 - 메뉴 - 더보기 - 설정
# 알림 설정
1. 알림설정
선택가능한 값은 3가지이다. 여기서 "상태표시줄 알림"이 기본 설정값으로 보이는데, "알리미 사용"으로 변경했다.
- 알리미 사용
- 상태표시줄 알림
- 사용안함
2. 알림음 선택
해당 일정에 대해 알려줄때 사용한 멜로리 선택이다.
3. 진동
선택가능한 값은 3가지이다. 기본 설정값이 "무음시에만" 이었나 그랬는데, "항상"으로 변경했다.
- 항상
- 무음시에만
- 사용안함
4. 기본알림시간
기본값은 10분.


Posted by fromm0
|
# 사용가능 계정 타입
최근에야 안 사실인데, 2.2인 프로요로 오면서 폰에서 자동 동기화가 가능한 타입이 3개이다.
1. Exchange
2. 페이스 북
3. 구글

Exchange 는 대개의 회사에서 주로 사용하는 메일이나 캘린더 서비스가 사용하는 Exchange Server 연동을 위한 것이다. 우리 회사도 이걸 사용하고 있어 이번에 셋팅하니, 사내 메일과 일정 모두 동기화가 가능해서 유용하게 사용하고 있다.

# 설정 위치 및 설정방법
1. 설정위치 : 설정 - 계정및 동기화 - 계정추가 (회사, Facebook, Google)
2. 설정방법
- 먼저 메일주소와 비밀번호를 입력하는 화면에서 적절히 값을 입력하면 된다.
- 서버/사용자명, 비밀번호, 서버, 보안연결사용 등을 적절히 입력하면 된다.


Posted by fromm0
|
자세한 내용은 http://3030.tistory.com/59 에서 가져왔음.

최근 회사 컴퓨터를 Win 7으로 바꾸면서, ERwin 실행시 오류가 발생했다.

[오류메시지]
오류 Input file: <파일명>.ER1 with file version: -1 is not readable by Computer Associates ERwin

[해결방법]
사용 중인 OS 가 Vista 혹은 Window 7인 경우, ERwin을읽지 못하여 생기는 문제.
ERwin이 설치되어 있는 폴더에 가서 (기본적으로 C:Program FilesCAAllFusion ERwin Data Modeler에 설치 됩니다.) MMOPN32.exe 파일의 속성으로 갑니다. 
호환성 탭으로 이동한 후, 호환성 모드의 '다음에 대해 호환성 모드로 이 프로그램 실행'을 체크하시고 window XP를 선택하면 됩니다.


Posted by fromm0
|
▣ 에러에 대한 설명
애기 보느라 계속 집중하지 못해 주말 내내 보고 있는 에러이다.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.validation.beanvalidation.LocalValidatorFactoryBean#0': Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: Could not initialize class org.hibernate.validator.engine.ConfigurationImpl
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1412)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:574)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:442)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:458)
    at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:339)
    at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:306)
    at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:127)
    at javax.servlet.GenericServlet.init(GenericServlet.java:212)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1161)
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:981)
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4058)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:4364)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
    at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
    at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
    at org.apache.catalina.core.StandardService.start(StandardService.java:516)
    at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
    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.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.hibernate.validator.engine.ConfigurationImpl
    at org.hibernate.validator.HibernateValidator.createGenericConfiguration(HibernateValidator.java:43)
    at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:269)
    at org.springframework.validation.beanvalidation.LocalValidatorFactoryBean.afterPropertiesSet(LocalValidatorFactoryBean.java:161)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1469)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1409)
    ... 32 more

Spring MVC 에 JSR 303 Bean Validator 를 적용하기 위해 Hibernate Validator 를 사용하는데 에러가 발생한다.
특별히 설정한게 없다. 그냥 Hibernate Validator 를 위해 pom.xml 파일에 아래 설정이 다인데.

        <dependency>
             <groupId>org.hibernate</groupId>
             <artifactId>hibernate-validator</artifactId>
             <version>4.1.0.Final</version>
         </dependency>



해결방법
이거 어디서 사용하는 거야.. 라며 지웠던 것이 원인이었다.T.T
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.5.10</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.5.10</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.5.10</version>
            <scope>runtime</scope>
        </dependency>



  관련URL
1. http://blog.inflinx.com/2010/03/10/jsr-303-bean-validation-using-spring-3/
2. http://codemunchies.com/2010/07/spring-mvc-form-validation-with-hibernate-validator/
Posted by fromm0
|

[메모] NoSQL

링크모음 2010. 8. 14. 13:37
# NoSQL

# MongoDB

관심을 가지고 조금 보려고 한다.
이번 프로젝트에서 운이 좋게(?) DL이 되지 않아, 오랜만에 기술적인 부분에 세부적으로 파고들고 있다.

'링크모음' 카테고리의 다른 글

[링크모음] 성능  (0) 2009.01.30
[링크모음] Java SE  (0) 2008.11.02
[링크모음] Web Service(SOAP, REST 등)  (0) 2008.11.02
Posted by fromm0
|
Spring이 버전을 업그레이드하면서 문서를 보면 역시 아쉬운 건 실제 적용된 샘플 소스인거 같습니다.
그래서인지 Spring사이트에서도 간단한 샘플을 이미 제공하고 있는데요..
주소가 https://src.springframework.org/svn/spring-samples/ 입니다.



좀더 다양하게 연동되어 완성된 애플리케이션 샘플이야 AppFuse를 보면 되지만, 특정 부분만 바로 파악하기 위해서는 아무래도 해당 부분만 적용된 샘플이 아쉬울수 밖에 없다고 보여지네요.

근데 이 샘플 소스를 받아 돌려도면 간혹 아래와 같은 에러가 발생합니다.

# 에러 메시지
org.apache.jasper.JasperException: Unable to read TLD "META-INF/c.tld" from JAR file "file:/D:/MyLucy/workspace/SPRING_SAMPLE/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/mvc-basic/WEB-INF/lib/jstl-1.2.jar": org.apache.jasper.JasperException: Failed to load or instantiate TagLibraryValidator class: org.apache.taglibs.standard.tlv.JstlCoreTLV

# 에러 메시지 화면


해결하기 위해서는 WEB-INF/lib 아래 Tomcat이 가지는 jar파일과 중복되는 두가지 파일을 지워주시면 됩니다.
WAS가 Tomcat이 아니라면 다른 에러가 뜰수도 있겠네요. ^^






Posted by fromm0
|