Add java1.5 system proxy support, as per bug 36174.
authorSteve Loughran <stevel@apache.org>
Wed, 17 Aug 2005 13:59:28 +0000 (13:59 +0000)
committerSteve Loughran <stevel@apache.org>
Wed, 17 Aug 2005 13:59:28 +0000 (13:59 +0000)
I do not see any evidence of this working on my kde/linux system; I will check out and test on Windows.Other tests on other platforms welcome.

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@278520 13f79535-47bb-0310-9956-ffa450edef68

WHATSNEW
docs/manual/installlist.html
docs/manual/proxy.html [new file with mode: 0644]
src/main/org/apache/tools/ant/Main.java
src/main/org/apache/tools/ant/util/ProxySetup.java [new file with mode: 0644]

index 9d8f0dc..ee383c3 100644 (file)
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -56,6 +56,13 @@ Changes that could break older environments:
   Scripts which previously used timediffmillis to do this compensation may 
   need to be rewritten.  timediffmillis has now been deprecated.
 
+* On Java1.5+, Ant automatically sets the system property
+  java.net.useSystemProxies to true, which gives it automatic use of the local
+  IE (Windows) or Gnome2 (Unix/Linux) proxy settings. This may break any build
+  file that somehow relied on content outside the firewall being unreachable:
+  use the -noproxy command-line option to disable this new feature, or set
+  
+
 
 Fixed bugs:
 -----------
index 7c22b0c..f324dc0 100644 (file)
@@ -18,6 +18,7 @@
   <a href="install.html#buildingant">Building Ant</a><br>
   <a href="install.html#librarydependencies">Library Dependencies</a><br>
   <a href="platform.html">Platform Specific Issues</a><br>
+  <a href="proxy.html">Proxy configuration</a><br>
 </p>
 <p><br>
 </p>
diff --git a/docs/manual/proxy.html b/docs/manual/proxy.html
new file mode 100644 (file)
index 0000000..8bc507b
--- /dev/null
@@ -0,0 +1,194 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+<title>Proxy Configuration</title>
+</head>
+
+<body>
+<h2>Proxy Configuration</h2>
+
+<p>
+
+All tasks running in Ant's JVM share the same HTTP/FTP/Socks
+proxy configuration.
+</p>
+
+<p>
+    When any task tries to retrieve content from an HTTP page, including the
+    <code>&lt;get&gt;</code> task, any automated URL retrieval in
+    an XML/XSL task, or any third-party task that uses the <code>java.net.URL</code>
+    classes, the proxy settings may make the difference between success and failure.
+</p>
+<p>
+    Anyone authoring a build file behind a blocking firewall will immediately appreciate
+    the problems and may want to write a build file to deal with the problem, but
+    users of third party build build files may find that the build file itself
+    does not work behind the firewall.
+</p>
+<p>
+    This is a longstanding problem with Java and Ant, which Java1.5 finally 
+    addresses. When Ant is run under Java1.5, it automatically sets the 
+    <code>java.net.useSystemProxies</code> system property, telling the JVM to 
+    switch to the OS-configured proxy settings.This is automatic, but it can be disabled.
+</p>
+<p>
+    When running Ant on older JVMs, this property is ignored. There are two other
+    ways to configure Ant's proxy settings in these cases.
+</p>
+
+
+
+<h3>Java1.5 automatic proxy support (new for Ant1.7)</h3>
+<p>
+    When Ant starts up, it automatically sets the 
+    <code>java.net.useSystemProxies</code> system property. This tells 
+    a Java1.5+ JVM to use the current set of property settings of the host
+    environment. Other JVMs, such as the Kaffe and Apache Harmony runtimes,
+    may also use this property in future, which is why Ant always sets the
+    property -it is ignored on the Java1.4 and earlier runtimes.
+</p>
+<p>
+    This property should be enough to automatically give Ant hosted
+    builds network access. It may also work under an IDE, though that depends
+    upon the IDE and how it starts ant. If it bypasses Ant's Main entry point,
+    the proxy setup may be skipped, and if networking has already started up
+    by the time ant is run, the option may be ignored. Consult your IDE 
+    documentation for IDE-specific information upon proxy setup.
+</p>
+<p>
+    To disable this automatic feature, set the command line option
+    <tt>-noproxy</tt>, or set a JVM or Ant property 
+    <code>java.net.useSystemProxies</code> to a value other than
+    <code>true</code> or <code>on</code>. If the JVM option is already set, 
+    Ant will not touch it; if an Ant property of that name is set, Ant will
+    pass the value of that property down to the JVM.
+</p>
+<p>
+    We are not entirely sure where it reads the property settings from. 
+    For windows, it probably reads the appropriate bits of the registry. For
+    Unix/Linux it may use the current Gnome2 settings. 
+    
+<p>
+    The biggest limitation of this feature, other than requiring a 1.5+ JVM,
+    is that it is not dynamic. A long-lasting build hosted on a laptop will
+    not adapt to changes in proxy settings. Furthermore, unless the user
+    is running <a
+    href="http://www.hpl.hp.com/techreports/2001/HPL-2001-158.html">an adaptive
+    laptop</a>, the host's proxy settings will not-automatically adapt to
+    changes in network context. The <code>-noproxy</code> option may be a useful
+    one to use when roaming.
+</p>
+
+<h3>JVM options</h3>
+<p>
+    Any JVM can have its proxy options explicitly configured by passing
+    the appropriate <code>-D</code> system property options to the runtime.
+    Ant can be configured through all its shell scripts via the
+    <code>ANT_OPTS</code> environment variable, which is a list of options to
+    supply to Ant's JVM:
+</p>
+<p>
+  For bash:
+</p>  
+<pre>
+    export ANT_OPTS="-Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080"
+</pre>
+  For csh/tcsh:
+<pre>
+    setenv ANT_OPTS "-Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080"
+</pre>
+<p>
+  For Windows, set the ANT_OPTS environment variable in the appropriate "MyComputer" 
+  properties dialog box.
+</p>
+<p>
+  This mechanism works across Java versions, is cross-platform and reliable. 
+  Once set, all build files run via the command line will automatically have
+  their proxy setup correctly, without needing any build file changes. It also
+  apparently overrides ants automatic proxy settings options 
+</p>
+<p>  
+  It is limited in the following ways:
+</p>  
+  <ol>
+  <li>Does not work under IDEs. These need their own proxy settings changed</li>
+  <li>Not dynamic enough to deal with laptop configuration changes.</li>
+  </ol>
+<p>  
+    If you are using Ant on a pre-Java1.5 machine behind a firewall, this is
+    the simplest and best way to configure your runtime to work with build files
+    that go beyond the firewall.
+</p>
+
+<h3>SetProxy Task</h3>
+<p>
+    The <a href="OptionalTasks/setproxy.html">setproxy task</a> can be used to
+    explicitly set a proxy in a build file. This manipulates the many proxy 
+    configuration properties of a JVM, and controls the proxy settings for all 
+    network operations in the same JVM from that moment. 
+</p>
+<p>
+    If you have a build file that is only to be used in-house, behind a firewall, on
+    an older JVM, <i>and you cannot change Ant's JVM proxy settings</i>, then
+    this is your best option. It is ugly and brittle, because the build file now contains
+    system configuration information. It is also hard to get this right across
+    the many possible proxy options of different users (none, HTTP, SOCKS).
+</p>
+
+
+<p>
+    Note that proxy configurations set with this task will probably override
+    any set by other mechanisms. It can also be used with fancy tricks to 
+    only set a proxy if the proxy is considered reachable:
+</p>
+
+<pre>
+  &lt;target name="probe-proxy" depends="init"&gt;
+    &lt;condition property="proxy.enabled"&gt;
+      &lt;and&gt;
+        &lt;isset property="proxy.host"/&gt;
+        &lt;isreachable host="${proxy.host}"/&gt;
+      &lt;/and&gt;
+    &lt;/condition&gt;
+  &lt;/target&gt;
+
+  &lt;target name="proxy" depends="probe-proxy" if="proxy.enabled"&gt;
+    &lt;property name="proxy.port" value="80"/&gt;
+    &lt;property name="proxy.user" value=""/&gt;
+    &lt;property name="proxy.pass" value=""/&gt;
+    &lt;setproxy proxyhost="${proxy.host}" proxyport="${proxy.port}"
+      proxyuser="${proxy.user}" proxypassword="${proxy.pass}"/&gt;
+  &lt;/target&gt;
+</pre>
+
+<h3>Summary and conclusions</h3>
+<p>
+There are three ways to set up proxies in Ant.
+</p>
+<ol>
+<li>Automatically, with Ant1.7 -use <code>-noproxy</code> to disable this.</li>
+<li>Via JVM system properties -set these in the ANT_ARGS environment variable.</li>
+<li>Via the &lt;setproxy&gt; task.</li>
+</ol>
+
+<p>
+As Java1.5 adoption increases, automatic proxy support should become more
+widespread. For this reason, we would encourage users not to try and
+second-guess network configurations with setproxy, and instead to encourage
+users to move up to Ant1.7/Java1.5, and if they cannot, to set proxy options
+in the ANT_ARGS environment variable.
+</p>
+
+<h4>Further reading</h4>
+
+<ul>
+<li><a href="http://java.sun.com/j2se/1.5.0/docs/guide/net/properties.html">
+Java Networking Properties</a>. Notice how not all proxy settings are documented
+there.
+<li><a href="http://blogs.sun.com/roller/resources/jcc/Proxies.pdf">Proxies</a>
+</li>
+</ul>
+</body>
+</html>
\ No newline at end of file
index 0071a32..97aa852 100644 (file)
@@ -31,6 +31,7 @@ import org.apache.tools.ant.input.InputHandler;
 import org.apache.tools.ant.launch.AntMain;
 import org.apache.tools.ant.util.ClasspathUtils;
 import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.ProxySetup;
 
 
 /**
@@ -121,6 +122,11 @@ public class Main implements AntMain {
     private Integer threadPriority = null;
 
     /**
+     * proxy flag: default is true
+     */
+    private boolean proxy=true;
+
+    /**
      * Prints the message of the Throwable if it (the message) is not
      * <code>null</code>.
      *
@@ -423,6 +429,8 @@ public class Main implements AntMain {
                         + "\nThis can be caused by a version mismatch between "
                         + "the ant script/.bat file and Ant itself.";
                 throw new BuildException(msg);
+            } else if (arg.equals("-noproxy")) {
+                proxy=false;
             } else if (arg.startsWith("-")) {
                 // we don't have any more args to recognize!
                 String msg = "Unknown argument: " + arg;
@@ -627,6 +635,8 @@ public class Main implements AntMain {
                     }
                 }
 
+
+
                 project.init();
                 project.setUserProperty(MagicNames.ANT_VERSION, getAntVersion());
 
@@ -642,6 +652,11 @@ public class Main implements AntMain {
                                         buildFile.getAbsolutePath());
 
                 project.setKeepGoingMode(keepGoingMode);
+                if (proxy) {
+                    //proxy setup if enabled
+                    ProxySetup proxySetup = new ProxySetup(project);
+                    proxySetup.enableProxies();
+                }
 
                 ProjectHelper.configureProject(project, buildFile);
 
@@ -809,7 +824,8 @@ public class Main implements AntMain {
                    + lSep);
         msg.append("  -nouserlib             Run ant without using the jar files from" + lSep
                    + "                         ${user.home}/.ant/lib" + lSep);
-        msg.append("  -noclasspath           Run ant without using CLASSPATH");
+        msg.append("  -noclasspath           Run ant without using CLASSPATH" + lSep);
+        msg.append("  -noproxy               Java 1.5 only: do not use the OS proxies");
         System.out.println(msg.toString());
     }
 
diff --git a/src/main/org/apache/tools/ant/util/ProxySetup.java b/src/main/org/apache/tools/ant/util/ProxySetup.java
new file mode 100644 (file)
index 0000000..df69027
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright  2005 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import org.apache.tools.ant.Project;
+
+/**
+ * Code to do proxy setup. This is just factored out of the main system just for
+ * @since Ant1.7
+ */
+
+public class ProxySetup {
+
+    private Project owner;
+
+    /**
+     * Java1.5 property that enables use of system proxies.
+     * @value
+     */
+    public static final String USE_SYSTEM_PROXIES="java.net.useSystemProxies";
+
+
+    /**
+     * create a proxy setup class bound to this project
+     * @param owner
+     */
+    public ProxySetup(Project owner) {
+        this.owner = owner;
+    }
+
+    /**
+     * Get the current system property settings
+     * @return current value; null for none or no access
+     */
+    public static String getSystemProxySetting() {
+        try {
+            return System.getProperty(USE_SYSTEM_PROXIES);
+        } catch (SecurityException e) {
+            //if you cannot read it, you wont be able to write it either
+            return null;
+        }
+    }
+
+    /**
+     * turn proxies on;
+     * if the proxy key is already set to some value: leave alone.
+     * if an ant property of the value {@link #USE_SYSTEM_PROXIES}
+     * is set, use that instead. Else set to "true".
+     */
+    public void enableProxies() {
+        if(!(getSystemProxySetting() != null)) {
+            String proxies =owner.getProperty(USE_SYSTEM_PROXIES);
+            if(proxies ==null || Project.toBoolean(proxies)) {
+                proxies ="true";
+            }
+            String message = "setting " + USE_SYSTEM_PROXIES + " to " + proxies;
+            try {
+                owner.log(message,Project.MSG_DEBUG);
+                System.setProperty(USE_SYSTEM_PROXIES,proxies);
+            } catch (SecurityException e) {
+                owner.log("Security Exception when "+message);
+            }
+        }
+    }
+
+}