javahttp代理设置将被缓存,直到JVM重新启动



我正在尝试更改用户界面中JVM的代理设置(运行在Java 1.6.0.23上的Eclipse应用程序(

if (isUseProxy()) {
    System.setProperty("java.net.useSystemProxies", "true");
    System.setProperty("http.proxyHost", getProxyHost());
    System.setProperty("http.proxyPort", getProxyPort());
    System.setProperty("https.proxyHost", getProxyHost());
    System.setProperty("https.proxyPort", getProxyPort());
    ..........
} else {
    System.clearProperty("http.proxyHost");
    System.clearProperty("http.proxyPort");
    System.clearProperty("https.proxyHost");
    System.clearProperty("https.proxyPort");
}

问题是,在JVM重新启动之前,NEW代理服务器值不会被使用,它被缓存在Java中的某个地方。

Java版本:

java.runtime.version=1.6.0_26-b03
java.specification.name=Java Platform API Specification
java.specification.vendor=Sun Microsystems Inc.

更新:魔术还在继续。。。我试图隔离这个问题,以弄清楚Java是如何神奇地与system.properties一起工作的。在某些随机情况下,Java似乎忽略了无效的代理服务器设置。此测试失败:

import org.junit.Test;
import java.io.IOException;
import java.net.*;
import static org.junit.Assert.fail;
public class ProxySetTest {
  @Test
  public void verifyProxyIsNotCachedInJVM() throws IOException {
    tryConnectionToGoogleCom();
    System.setProperty("http.proxyHost", getInvalidProxyHost());
    System.setProperty("http.proxyPort", getInvalidProxyPort()+"");
    System.setProperty("https.proxyHost", getInvalidProxyHost());
    System.setProperty("https.proxyPort", getInvalidProxyPort()+"");
    // Next connection will be through the invalid proxy. must fail?
    try {
      tryConnectionToGoogleCom();
      fail("must have failed with an exception because of invalid proxy setting");
    } catch (Exception e) {
      System.out.println("received exception: " + e);
    }
    // clear the proxy setting and try connecting again - must succeed
    System.clearProperty("http.proxyHost");
    System.clearProperty("http.proxyPort");
    System.clearProperty("https.proxyHost");
    System.clearProperty("https.proxyPort");
    // and without proxy again
    tryConnectionToGoogleCom();
  }
  private void tryConnectionToGoogleCom() throws IOException {
    URL url = new URL("http://google.com");
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.connect();
  }
  private int getInvalidProxyPort() {
    return 1234;
  }
  private String getInvalidProxyHost() {
    return "asd";
  }
}

所以我遇到了完全相同的问题,并已将其追踪到axis缓存信息。

它在org.apache.axis.components.net.TransportClientProperties Factory 中

有问题的方法是:

public static TransportClientProperties create(String protocol)
{
    TransportClientProperties tcp =
        (TransportClientProperties)cache.get(protocol);
    if (tcp == null) {
        tcp = (TransportClientProperties)
            AxisProperties.newInstance(TransportClientProperties.class,
                                       (Class)defaults.get(protocol));
        if (tcp != null) {
            cache.put(protocol, tcp);
        }
    }
    return tcp;
}

在第一次调用中,无论代理的当前JVM设置是什么,都会创建tcp对象。在随后的调用中,它会提取缓存的版本,所以即使您已经更改了JVM中的代理设置,也没关系。想看看我是否能找到清除缓存的方法。

package com.alskor;
import org.junit.Test;
import java.io.IOException;
import java.net.*;
import static org.junit.Assert.fail;
public class ProxySetTest {
  @Test
  public void verifyProxyIsNotCachedInJVM() throws IOException {
    tryConnectionToGoogleCom();
    ProxySelector savedSelector = ProxySelector.getDefault();
    java.net.ProxySelector.setDefault(new FixedProxySelector(getInvalidProxyHost(), getInvalidProxyPort()));
    // Next connection will be through the invalid proxy. must fail?
    try {
      tryConnectionToGoogleCom();
      fail("must have failed with an exception because of invalid proxy setting");
    } catch (Exception e) {
      System.out.println("received exception: " + e);
    }
    // clear the proxy setting and try connecting again - must succeed
    java.net.ProxySelector.setDefault(savedSelector);
    // and without proxy again
    tryConnectionToGoogleCom();
  }
  private void tryConnectionToGoogleCom() throws IOException {
    URL url = new URL("http://google.com");
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.connect();
  }
  private int getInvalidProxyPort() {
    return 1234;
  }
  private String getInvalidProxyHost() {
    return "asd";
  }
}

package com.alskor;
import sun.misc.RegexpPool;
import java.io.IOException;
import java.net.*;
import java.util.ArrayList;
import java.util.List;
public class FixedProxySelector extends ProxySelector {
  private final String host;
  private final int port;
  public FixedProxySelector(String host, int port) {
    this.host = host;
    this.port = port;
  }
  @Override
  public java.util.List<Proxy> select(URI uri) {
    if (uri == null) {
      throw new IllegalArgumentException("URI can't be null.");
    }
    List<Proxy> proxies = new ArrayList<Proxy>();
    SocketAddress addr = new InetSocketAddress(host, port);
    proxies.add(new Proxy(Proxy.Type.SOCKS, addr));
    proxies.add(new Proxy(Proxy.Type.HTTP, addr));
    return proxies;
  }
  @Override
  public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
    if (uri == null || sa == null || ioe == null) {
      throw new IllegalArgumentException("Arguments can't be null.");
    }
    throw new RuntimeException(ioe.toString(), ioe);
  }
}

将java.net.Proxy对象传递到URL.openConnection(Proxy(方法。您可以使用Proxy.NO_Proxy进行直接连接。或者创建这样的新代理:

new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 8080))

这是一个完整的样本:

public class TestConnectOverProxy {
  static class Connector {
    private Proxy proxy = Proxy.NO_PROXY;
    public void setProxy(Proxy proxy) {
      this.proxy = proxy;
    }
    /**
     * This method works with java.net.Proxy field of the Connector class
     * as described
     * <a href="http://www.rgagnon.com/javadetails/java-0085.html">here</a>
     */
    public String getContent(URL url) throws IOException {
      HttpURLConnection conn = (HttpURLConnection) url.openConnection(proxy);
      conn.connect();
      System.out.println(conn.getRequestMethod());
      System.out.println(conn.getResponseCode());
      return IOUtils.toString(conn.getInputStream());
    }
  }
  @Test
  public void test() throws IOException {
    URL url = new URL("http://www.google.com");
    Connector connector = new Connector();

    //connect directly
    connector.setProxy(Proxy.NO_PROXY);
    System.out.println(connector.getContent(url));
    //connect over proxy
    connector.setProxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 8080)));
    System.out.println(connector.getContent(url));
  }
}

最新更新