TypeError: Cannot read property 'createElement' of undefined 의 에러가 발생한다면 import 구문을 확인해보자 보통 우리는 여러개의 library를 { }을 사용해서 한번에 import를 하게 된다.

import { .... } from 'library';

클래스 컴포넌트를 생성하기 위해서는 Component를 import를 해야 하는데, 만약 아래와 같이 import 한다면 에러가 발생한다.

import { React, Component } from 'react';

issue 를 살펴보면 아래와 같이 선언을 하라고 한다.

import React, { Component } from 'react';

maven에 새 jar를 추가하고 application을 실행해보니 아래와 같은 메세지가 나온다.

오류메세지

:A child container failed during start  
[java.util.concurrent.ExecutionException:](java.util.concurrent.ExecutionException:) [org.apache.catalina.LifecycleException:](org.apache.catalina.LifecycleException:) Failed to start component \[StandardEngine\[Tomcat\].StandardHost\[localhost\].StandardContext\[\]\]  
at [java.util.concurrent.FutureTask.report(FutureTask.java:122)](java.util.concurrent.FutureTask.report(FutureTask.java:122)) ~\[?:1.8.0\_77\]  
at [java.util.concurrent.FutureTask.get(FutureTask.java:192)](java.util.concurrent.FutureTask.get(FutureTask.java:192)) ~\[?:1.8.0\_77\]  
at [org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:911)](org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:911)) \[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  
at [org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:890)](org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:890)) \[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  
at [org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)](org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)) \[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  
at [org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1403)](org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1403)) \[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  
at [org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393)](org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393)) \[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  
at [java.util.concurrent.FutureTask.run(FutureTask.java:266)](java.util.concurrent.FutureTask.run(FutureTask.java:266)) \[?:1.8.0\_77\]  
at [java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)](java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)) \[?:1.8.0\_77\]  
at [java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)](java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)) \[?:1.8.0\_77\]  
at [java.lang.Thread.run(Thread.java:745)](java.lang.Thread.run(Thread.java:745)) \[?:1.8.0\_77\]  
Caused by: [org.apache.catalina.LifecycleException:](org.apache.catalina.LifecycleException:) Failed to start component \[StandardEngine\[Tomcat\].StandardHost\[localhost\].StandardContext\[\]\]  
at [org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167)](org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167)) ~\[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  
... 6 more  
Caused by: [org.apache.catalina.LifecycleException:](org.apache.catalina.LifecycleException:) Failed to start component \[Pipeline\[StandardEngine\[Tomcat\].StandardHost\[localhost\].StandardContext\[\]\]\]  
at [org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167)](org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167)) ~\[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  
at [org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5099)](org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5099)) ~\[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  

해결방법

검색해보니 servlet-api.jar를 exclude하라는 말이 많이 나왔는데
나의 경우 아래 설정을 pom에 추가하니 실행 성공하였다.

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
</dependency>

provided 는 무엇을 의미하는지?

This scope is used to mark dependencies that should be provided at runtime by JDK or a container, hence the name.

A good use case for this scope would be a web application deployed in some container, where the container already provides some libraries itself.
컨테이너에서 deploy도는 어플리케이션에서 컨테이너는 이미 자체적인 라이브러리를 제공한다.

For example, a web server that already provides the Servlet API at runtime, thus in our project, those dependencies can be defined with the provided scope:
런타임에 의존성을 가지지 않고 컴파일/테스트단계에서만 제공되는 dependency.

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
</dependency>

The provided dependencies are available only at compile-time and in the test classpath of the project; what's more, they aren't transitive.

라이브러리 의존성을 피하기 위한 방법이리라.

+ Recent posts