Skip to content

[FIX] avoid UnreachableBrowserException when creating WebDriver instance#14

Closed
curva wants to merge 1 commit intoSeleniumHQ:masterfrom
curva:circular_redirect_exception_spike
Closed

[FIX] avoid UnreachableBrowserException when creating WebDriver instance#14
curva wants to merge 1 commit intoSeleniumHQ:masterfrom
curva:circular_redirect_exception_spike

Conversation

@curva
Copy link

@curva curva commented Feb 12, 2013

Summary:
Avoid multiple call for org.webbitserver.HttpResponse#end(), which flushes http response to tcp stream in rare cases. This causes UnreachableBrowserException when creating WebDriver instance (see exception message below [*1]).

Detail:
When a test code creates WebDriver instance, WebDriver(client) sends new session request. If WebDriver(server) receives that request, server renders response using RedirectResult#render() and flushes it using WebbitHttpResponse#end().
But there's a issue that WebbitHttpResponse#end() is called two times (see below[*2]).
WebbitHttpResponse#end() calls Webbit's NettyHttpResponse#end() that flushes http response to tcp stream. So WebDriver client gets same response two times as described below:

HTTP/1.1 303 See Other
Location: /wd/hub/session/

If WebDriver client gets redirect response two times, a CircularRedirectException will be thrown by apache http client which results in UnreachableBrowserException.
That's why WebbitHttpResponse should call webbit's HttpResponse#end() just one time.

Remarks:
(*1) UnreachableBrowserException Stacktrace

org.openqa.selenium.remote.UnreachableBrowserException: Could not start a new session. Possible causes are invalid address of the remote server or browser start-up failure.
Build info: version: '2.29.0', revision: '58258c3', time: '2013-01-17 22:47:00'
System info: os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.6.8', java.version: '1.6.0_39'
Driver info: driver.version: AndroidDriver
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:527)
    at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:216)
    at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:111)
    at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:129)
    at org.openqa.selenium.android.AndroidDriver.<init>(AndroidDriver.java:81)
    at org.openqa.selenium.android.AndroidDriver.<init>(AndroidDriver.java:73)
    at ReproductionTest.setup(ReproductionTest.java:42)
    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:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:24)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    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)
Caused by: org.apache.http.client.ClientProtocolException
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:909)
    at org.openqa.selenium.remote.HttpCommandExecutor.fallBackExecute(HttpCommandExecutor.java:331)
    at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:310)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:506)
    ... 38 more
Caused by: org.apache.http.client.CircularRedirectException: Circular redirect to 'http://192.168.0.7:8080/wd/hub/session/5559153d-0123-446d-9be4-02e01c8a33c3'
    at org.apache.http.impl.client.DefaultRedirectStrategy.getLocationURI(DefaultRedirectStrategy.java:175)
    at org.apache.http.impl.client.DefaultRedirectStrategy.getRedirect(DefaultRedirectStrategy.java:209)
    at org.apache.http.impl.client.DefaultRequestDirector.handleResponse(DefaultRequestDirector.java:1068)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:545)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
    ... 41 more

(*2) Caller of WebbitHttpResponse#end()
first one is:

  • org.openqa.selenium.remote.server.rest.ResultConfig#handle()

second one is either of them below:

  • org.openqa.selenium.remote.server.renderer.JsonResult#render()
  • org.openqa.selenium.remote.server.renderer.RedirectResult#render()
    -> org.openqa.selenium.remote.server.WebbitHttpResponse#sendRedirect()

Reproduction Code:

import java.util.ArrayList;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.android.AndroidDriver;
import org.openqa.selenium.remote.UnreachableBrowserException;

@RunWith(Parameterized.class)
public class ReproductionTest {
    WebDriver driver = null;

    public ReproductionTest(String dummy) {
    }

    @Parameters
    public static List<String[]> dummyData() {
        // Dummy parameter method.
        // This is just for calling setup/tearDown method many times.

        int params = 1000;

        List<String[]> dummy = new ArrayList<String[]>();
        for(int i = 0; i < params; i++) {
            dummy.add(new String[] { "" });
        }

        return dummy;
    }

    @Before
    public void setup() throws Exception {
        try {
            driver = new AndroidDriver();
        } catch(UnreachableBrowserException e) {
            e.printStackTrace();

            // sleep for a while to stop junit
            Thread.sleep(10 * 60 * 1000);
        }
    }

    @After
    public void tearDown() {
        driver.quit();
    }

    @Test
    public void testDummy() throws Throwable {
        // do nothing
    }
}

…end() method flushes response to tcp stream.
@shs96c
Copy link
Member

shs96c commented Jun 20, 2013

@alex-savchuk
Copy link
Contributor

It was fixed by similar code at revision 2f2cdf3

IlyaNaumovich added a commit to IlyaNaumovich/selenium that referenced this pull request Feb 11, 2018
yiming-tang-cs pushed a commit to ponder-lab/selenium that referenced this pull request Jan 2, 2020
yiming-tang-cs pushed a commit to ponder-lab/selenium that referenced this pull request Jan 2, 2020
SeleniumHQ#14:  reply with notify_close even if "we are a client"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants