Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 148E3200D4F for ; Wed, 6 Dec 2017 19:28:06 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 1300D160C0A; Wed, 6 Dec 2017 18:28:06 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 323D0160BF3 for ; Wed, 6 Dec 2017 19:28:05 +0100 (CET) Received: (qmail 72703 invoked by uid 500); 6 Dec 2017 18:28:04 -0000 Mailing-List: contact dev-help@felix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@felix.apache.org Delivered-To: mailing list dev@felix.apache.org Received: (qmail 72692 invoked by uid 99); 6 Dec 2017 18:28:04 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd2-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 06 Dec 2017 18:28:04 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd2-us-west.apache.org (ASF Mail Server at spamd2-us-west.apache.org) with ESMTP id 8EEA31A13E2 for ; Wed, 6 Dec 2017 18:28:03 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd2-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -100.002 X-Spam-Level: X-Spam-Status: No, score=-100.002 tagged_above=-999 required=6.31 tests=[RP_MATCHES_RCVD=-0.001, SPF_PASS=-0.001, USER_IN_WHITELIST=-100] autolearn=disabled Received: from mx1-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd2-us-west.apache.org [10.40.0.9]) (amavisd-new, port 10024) with ESMTP id A4i8DbK0GvKH for ; Wed, 6 Dec 2017 18:28:02 +0000 (UTC) Received: from mailrelay1-us-west.apache.org (mailrelay1-us-west.apache.org [209.188.14.139]) by mx1-lw-eu.apache.org (ASF Mail Server at mx1-lw-eu.apache.org) with ESMTP id 311FF5F306 for ; Wed, 6 Dec 2017 18:28:01 +0000 (UTC) Received: from jira-lw-us.apache.org (unknown [207.244.88.139]) by mailrelay1-us-west.apache.org (ASF Mail Server at mailrelay1-us-west.apache.org) with ESMTP id 6A012E04AB for ; Wed, 6 Dec 2017 18:28:00 +0000 (UTC) Received: from jira-lw-us.apache.org (localhost [127.0.0.1]) by jira-lw-us.apache.org (ASF Mail Server at jira-lw-us.apache.org) with ESMTP id 204C3255BF for ; Wed, 6 Dec 2017 18:28:00 +0000 (UTC) Date: Wed, 6 Dec 2017 18:28:00 +0000 (UTC) From: "Ali Kamali (JIRA)" To: dev@felix.apache.org Message-ID: In-Reply-To: References: Subject: [jira] [Created] (FELIX-5759) StackOverflowError thrown during URL construction MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 archived-at: Wed, 06 Dec 2017 18:28:06 -0000 Ali Kamali created FELIX-5759: --------------------------------- Summary: StackOverflowError thrown during URL construction Key: FELIX-5759 URL: https://issues.apache.org/jira/browse/FELIX-5759 Project: Felix Issue Type: Bug Reporter: Ali Kamali Priority: Critical I get the following callstack resulting in a stack overflow error when building a URL object: {code} [info] at org.apache.felix.framework.URLHandlersStreamHandlerProxy.parseURL(URLHandlersStreamHandlerProxy.java:401) [info] at java.net.URL.(URL.java:622) [info] at java.net.URL.(URL.java:490) [info] at org.apache.felix.framework.URLHandlersStreamHandlerProxy.parseURL(URLHandlersStreamHandlerProxy.java:401) [info] at java.net.URL.(URL.java:622) [info] at java.net.URL.(URL.java:490) [info] at org.apache.felix.framework.URLHandlersStreamHandlerProxy.parseURL(URLHandlersStreamHandlerProxy.java:401) [info] at java.net.URL.(URL.java:622) [info] at java.net.URL.(URL.java:490) [info] at org.apache.felix.framework.URLHandlersStreamHandlerProxy.parseURL(URLHandlersStreamHandlerProxy.java:401) [info] at java.net.URL.(URL.java:622) [info] at java.net.URL.(URL.java:490) [info] at org.apache.felix.framework.URLHandlersStreamHandlerProxy.parseURL(URLHandlersStreamHandlerProxy.java:401) [info] at java.net.URL.(URL.java:622) [info] at java.net.URL.(URL.java:490) [info] at org.apache.felix.framework.URLHandlersStreamHandlerProxy.parseURL(URLHandlersStreamHandlerProxy.java:401) [info] at java.net.URL.(URL.java:622) [info] at java.net.URL.(URL.java:490) [info] at org.apache.felix.framework.URLHandlersStreamHandlerProxy.parseURL(URLHandlersStreamHandlerProxy.java:401) {code} Using org.apache.felix.framework 4.4.1 and Java 1.8.0_111 running on Ubuntu. We started getting this exception after upgrading to Spark 2.2.0, after some investigation we realized Spark 2.2.0 registers its own {{URLStreamHandlerFactory}}: {code} package org.apache.spark.sql.internal object SharedState extends Logging { try { URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory()) } catch { case e: Error => logWarning("URL.setURLStreamHandlerFactory failed to set FsUrlStreamHandlerFactory") } ... {code} Looks like the bug is related to line 128 in {{URLHandlers.java}}: {code} URLStreamHandler handler = getBuiltInStreamHandler(protocol, factory); if (handler != null) { URL url = new URL(protocol, null, -1, "", handler); m_handlerToURL.put(handler, url); } {code} This code assumes there is a unique mapping from handlers to protocols, which doesn't seem to be a valid assumption, at least not with Spark. Spark URL handler factory is returning the same handler instance for both {{file}} and {{ftp}} protocols. When {{URLHandlers}} is initializing it first tries to register a handler for {{file}} and then for {{ftp}}, but because the factory returns the same handler we end up replacing the URL object we have for {{file}} with {{ftp}} in {{m_handlerToURL}}. Later when a URL is being constructed it calls {{createURLStreamHandler}} from URLHandlers, at the end of this method: {code} // If built-in content handler, then create a proxy handler. return addToStreamCache(protocol, new URLHandlersStreamHandlerProxy(protocol, m_secureAction, handler, (URL) m_handlerToURL.get(handler))); {code} Note that it's trying to use {{m_handlerToURL}} to look up the protocol for the handler, and in case of {{file}} instead of returning a URL with protocol set to {{file}} it returns a URL with protocol set to {{ftp}}, so {{URLHandlersStreamHandlerProxy}} gets constructed with {{m_builtInURL}} set to {{ftp}}. Later in URL.java we have this code: {code} if ((context != null) && ((newProtocol == null) || newProtocol.equalsIgnoreCase(context.protocol))) { // inherit the protocol handler from the context // if not specified to the constructor if (handler == null) { handler = context.handler; } {code} This code only uses the handler if protocols match, but in this case protocols don't match because it's expected to be {{file}} but we receive {{ftp}} that comes from {{m_builtInURL}}, and the code falls back to asking the factory to create a new handler: {code} if (handler == null && (handler = getURLStreamHandler(protocol)) == null) { throw new MalformedURLException("unknown protocol: "+protocol); } {code} The factory returns a handler with protocol set to {{ftp}} again and we get stuck in a loop. Looking at the newest Felix code looks like the assumption of having a unique handler per protocol is still there, so I believe this bug still exists in the newest Felix as well. To reproduce this bug before starting a bundle you only need to register a factory that returns the same handler instance for {{file}} and {{ftp}}. -- This message was sent by Atlassian JIRA (v6.4.14#64029)