복붙노트

[HADOOP] hadoop에서 스택 오버플로 오류 발생

HADOOP

hadoop에서 스택 오버플로 오류 발생

Java 코드를 사용하여 hadoop 파일에 액세스하는 동안 스택 오버플로 오류가 발생합니다.

import java.io.InputStream;
import java.net.URL;
import org.apache.hadoop.fs.FsUrlStreamHandlerFactory;
import org.apache.hadoop.io.IOUtils;
public class URLCat 
{
    static 
    {
            URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
    }

    public static void main(String[] args) throws Exception 
    {
        InputStream in = null;
        try 
        {
            in = new URL(args[0]).openStream();
            IOUtils.copyBytes(in, System.out, 4096, false);
        }
        finally 
        {
            IOUtils.closeStream(in);
        }
    }
}

나는이 코드를 디버깅하기 위해 이클립스를 사용했다. 그런 다음 줄을 알게되었다.

in = new URL(args[0]).openStream();

생산 오류.

내가이 코드를 실행하는 데있어 파일 경로가

 hdfs://localhost/user/jay/abc.txt

예외 (의견에서 가져옴) :

Exception in thread "main" java.lang.StackOverflowError
  at java.nio.Buffer.<init>(Buffer.java:174) 
  at java.nio.ByteBuffer.<init>(ByteBuffer.java:259) 
  at java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:52) 
  at java.nio.ByteBuffer.wrap(ByteBuffer.java:350) 
  at java.nio.ByteBuffer.wrap(ByteBuffer.java:373) 
  at java.lang.StringCoding$StringEncoder.encode(StringCoding.java:237) 
  at java.lang.StringCoding.encode(StringCoding.java:272) 
  at java.lang.String.getBytes(String.java:946) 
  at java.io.UnixFileSystem.getBooleanAttributes0(Native Method) 
  .. stack trace truncated ..

해결법

  1. ==============================

    1.1) 이것은 hadoop이 제공하는 FSURLStreamHandlerFactory 클래스의 버그 때문입니다. 버그는이 클래스가 포함 된 최신 jar에서 수정된다는 점에 유의하십시오.

    1) 이것은 hadoop이 제공하는 FSURLStreamHandlerFactory 클래스의 버그 때문입니다. 버그는이 클래스가 포함 된 최신 jar에서 수정된다는 점에 유의하십시오.

    2)이 파일은 hadoop-common-2.0.0-cdh4.2.1.jar에 있습니다. 문제를 완전히 이해하려면 java.net.URL 클래스가 어떻게 작동하는지 이해해야합니다.

    「URLStreamHandler」(파라미터로서 null를 건네 주거나 URLStreamHandler 객체를 파라미터로서 취하지 않는 생성자을 건네주는 것)를 건네주지 않고, 그 constructor 중 한쪽을 사용해 새로운 URL를 작성하면 (자), 내부적으로 getURLStreamHandler ()라고하는 메소드가 불려갑니다. 이 메서드는 URLStreamHandler 객체를 반환하고 멤버를 설정합니다.

    URL 클래스의 변수.

    이 객체는 "http", "file"...와 같은 특정 체계의 연결을 만드는 법을 알고 있습니다. 이 URLStreamHandler는, 다음의 팩토리에 의해 구축됩니다.

    URLStreamHandlerFactory.

    3) 위의 문제 예제에서 URLStreamHandlerFactory는 다음 정적 메서드를 호출하여 "FsUrlStreamHandlerFactory"로 설정되었습니다.

        URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
    

    따라서 새로운 URL을 만들면이 "FSUrlStreamHandlerFactory"가 createURLStreamHandler (protocol) 메서드를 호출하여이 새 URL에 대한 URLStreamHandler 객체를 만드는 데 사용됩니다.

    이 메소드는 FileSystem 클래스의 loadFileSystems () 메서드를 호출합니다. loadFileSystems () 메소드는 ServiceLoader.load ( "FileSystem.class")를 호출하여 classpath에있는 모든 jar 파일의 모든 META-INF / services / *. FileSystem 파일을 검색하여 FileSystem 구현 클래스의 이진 이름을 읽으려고 시도합니다. 그것의 입장을 읽는.

    4) 각 jar는 각 jar에 대한 URL 오브젝트로서 처리된다는 것을 기억하십시오. URL 오브젝트는 ClassLoader에 의해 내부적으로 작성됩니다. 클래스 로더는 URLStreamHandler 객체를 제공합니다.

    URL이 이미 "URLStreamHandler"를 가지고 있기 때문에 우리가 설정 한 "FSUrlStreamHandlerFactory"에 영향을받지 않도록이 jar에 대한 URL을 구성 할 때 사용됩니다. 우리는

    클래스 로더가 "sun.net.www.protocol.jar.Handler"유형의 "URLStreamHandler"를 설정하는 jar 파일을 처리합니다.

    5) 이제 File System 구현 클래스의 jar 파일 안의 항목을 읽으려면 "sun.net.www.protocol.jar.Handler"가 각 항목에 대한 URL 객체를 생성해야합니다.

    URLStreamHandler 객체없이 URL 생성자를 호출합니다. URLStreamHandlerFactory를 이미 "FSUrlStreamHandlerFactory"로 정의 했으므로 createURLStreamHandler를 호출합니다.

    indefinetly 재귀를 발생시키고 "StackOverflowException"을 발생시키는 (프로토콜) 메소드.

    이 버그는 Hadoop 커밋터에서 "HADOOP-9041"이라고합니다. 링크는 https://issues.apache.org/jira/browse/HADOOP-9041입니다.

    나는 이것이 다소 복잡하다는 것을 안다.

    그래서 간단히 말해서이 문제에 대한 해결책이 아래와 같습니다.

    1)이 버그에 대한 수정 사항이있는 최신 jar hadoop-common-2.0.0-cdh4.2.1.jar를 사용하십시오

    또는

    2) URLStreamHandlerFactory를 설정하기 전에 다음 블록을 정적 블록에 넣으십시오.

          static {
                   FileSystem.getFileSystemClass("file",new Configuration()); 
                   URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
                 } 
    

    정적 블록 내의 첫 번째 문은 이제 FsUrlStreamHandlerFactory에 의존하지 않고 file : //에 대한 기본 처리기를 사용하여 META-INF / services / *. FileSystem 파일의 파일 entire를 읽습니다.

  2. ==============================

    2.해결 방법이 있습니다.

    해결 방법이 있습니다.

    하둡 세계의 현재 상태 (2014 년 1 월)에 더 익숙한 사람이 우리를 계몽하고 행동을 설명하는 것이 좋을 것입니다.

    Hadoop에서 URLCat를 실행하려고 할 때 StackOverflowError와 동일한 문제가 발생했습니다. The Definitive Guide Third Edition Tom White

    Cloudera QuickStart 4.4.0 및 4.3.0에 문제가 있습니다.

    jdk1.6.0_32 및 jdk1.6.0_45 모두 사용

    이 문제는 java.net.URL 아래 org.apache.hadoop.fs.FileSystem의 초기화 / 클래스 로딩 중에 발생합니다. 재귀적인 예외 처리가 시작되고 있습니다. 나는 그것을 추적 할 수있는 최선을 다했다. 경로는 java.util.ServiceLoader로 이어지며 java.util.ServiceLoader는 sun.misc.CompoundEnumeration.nextElement ()를 호출합니다. 불행히도 sun.misc.CompoundEnumeration의 소스는 jdk src.zip에 포함되어 있지 않습니다 ... java 패키지 sun.misc에 있기 때문에 감시가 가능합니다.

    다른 실행 경로를 통해 오류를 트리거하기 위해 해결 방법이 생겼습니다 ...

    StreamHandlerFactory를 등록하기 전에 org.apache.hadoop.fs.FileSystem.getFileSystemClass (String, Configuration)을 호출하여 StackOverflowError로 연결되는 조건을 피할 수 있습니다.

    이는 정적 초기화 블록을 수정하여 수행 할 수 있습니다 (위의 원래 목록 참조).

       static {
            Configuration conf = new Configuration();
            try {
                FileSystem.getFileSystemClass("file", conf);
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage());
            };
            URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
        }
    

    이 정적 블록의 내용을 main ()으로 이동하여이 작업을 수행 할 수도 있습니다.

    FsUrlStreamHandlerFactory를 사용하여 stackoverflow에서 2011 년 8 월에이 오류에 대한 또 다른 참조를 발견했습니다.

    나는 더 많은 hadoop 초보자가이 문제에 걸리지 않았 음을 당혹 스럽다 ... Hadoop 책을 구입하라 ... Cloudera QuickStart를 다운로드 ... 아주 간단한 예제를 시도해 보라 ... FAIL !?

    경험이 많은 사람들의 통찰력은 인정 될 것입니다.

  3. from https://stackoverflow.com/questions/17360018/getting-stack-overflow-error-in-hadoop by cc-by-sa and MIT license