JDK-8038986 : Nashorn fails to evaluate autoconfig-script when used via JavaWS
  • Type: Bug
  • Component: deploy
  • Affected Version: 8
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_7
  • CPU: x86_64
  • Submitted: 2014-03-25
  • Updated: 2014-11-11
  • Resolved: 2014-04-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u20Fixed 9 b15Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b132)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)

java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b132)
Java HotSpot(TM) Client VM (build 25.0-b70, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

EXTRA RELEVANT SYSTEM CONFIGURATION :
No direct connection to the internet - only via http/socks-proxys

A DESCRIPTION OF THE PROBLEM :
The JavaScript engine Nashorn is unable to evaluate an autoproxy configuration when in deployment.properties deployment.proxy.auto.config.url is used and the autoconfig script contains any function that calls dnsResolve.

Common part of Exception is always
Caused by: <eval>:34 TypeError: com.sun.deploy.net.proxy.SunAutoProxyHandler@........ has no such function "dnsResolve"
.
.
.
	at jdk.nashorn.internal.scripts.Script$\^eval\_.dnsResolve(<eval>:34)
.
.
.
	at jdk.nashorn.internal.scripts.Script$\^eval\_.FindProxyForURL(<eval>:188)
	at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:502)

REGRESSION.  Last worked in version 7u51

ADDITIONAL REGRESSION INFORMATION: 
java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b132)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)

java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b132)
Java HotSpot(TM) Client VM (build 25.0-b70, mixed mode)

Also fails in jdk8 b128. Haven't tested older jdk8 builds.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Deploy an autoconfig.conf like this:
====================
function FindProxyForURL(url, host)
{
	if(dnsResolve(host) == '') {
		return "DIRECT"
	}
	if (isResolvable(host) && false)
	{
		return "DIRECT";
	}
	if (isInNet(host, "255.255.0.0", "255.255.0.0") && false)
	{
		return "DIRECT";
	}
	return "PROXY yourproxy:yourproxyport";
}
====================

2. Compile the following to a .class and place it in a signed jar along with an APPLICATION.jnlp etc.

Testclass:
====================
see below <Source code for an executable test case>
====================

3. Run your webstart-app

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
When executing url_.openConnection().getInputStream()
Nashorn should evaluate the autoconfig and select the right proxy.
ACTUAL -
Nashorn throws an exception whenever dnsResolve, isResolvable or isInNet is called. Other functions that in turn call dnsResolve may be affected, too.
No proxy is used then and the connection fails.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
javax.script.ScriptException: TypeError: com.sun.deploy.net.proxy.SunAutoProxyHandler@74a3b2dc has no such function "dnsResolve" in <eval> at line number 34
	at jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:564)
	at jdk.nashorn.api.scripting.NashornScriptEngine.invokeImpl(NashornScriptEngine.java:514)
	at jdk.nashorn.api.scripting.NashornScriptEngine.invokeFunction(NashornScriptEngine.java:229)
	at com.sun.deploy.net.proxy.SunAutoProxyHandler.getProxyInfo(Unknown Source)
	at com.sun.deploy.net.proxy.DynamicProxyManager.getProxyList(Unknown Source)
	at com.sun.deploy.net.proxy.DeployProxySelector.select(Unknown Source)
	at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(Unknown Source)
	at sun.net.www.protocol.http.HttpURLConnection$6.run(Unknown Source)
	at sun.net.www.protocol.http.HttpURLConnection$6.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessController.doPrivileged(Unknown Source)
	at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
	at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source)
	at com.sun.deploy.net.CrossDomainXML$3.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at com.sun.deploy.net.CrossDomainXML.privilegedConnect(Unknown Source)
	at com.sun.deploy.net.CrossDomainXML.check(Unknown Source)
	at com.sun.deploy.net.CrossDomainXML.check(Unknown Source)
	at com.sun.javaws.security.JavaWebStartSecurity.checkURLPermissionHelper(Unknown Source)
	at com.sun.javaws.security.JavaWebStartSecurity.checkPermission(Unknown Source)
	at sun.net.www.protocol.http.HttpURLConnection.URLtoSocketPermission(Unknown Source)
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
	at testapp.Testapp.fetchHtml(Testapp.java:31)
	at testapp.Testapp.<init>(Testapp.java:19)
	at testapp.Testapp.main(Testapp.java:49)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at com.sun.javaws.Launcher.executeApplication(Unknown Source)
	at com.sun.javaws.Launcher.executeMainClass(Unknown Source)
	at com.sun.javaws.Launcher.doLaunchApp(Unknown Source)
	at com.sun.javaws.Launcher.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
Caused by: <eval>:34 TypeError: com.sun.deploy.net.proxy.SunAutoProxyHandler@74a3b2dc has no such function "dnsResolve"
	at jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:56)
	at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:212)
	at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:184)
	at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:171)
	at jdk.nashorn.internal.runtime.linker.NashornBottomLinker.linkBean(NashornBottomLinker.java:118)
	at jdk.nashorn.internal.runtime.linker.NashornBottomLinker.getGuardedInvocation(NashornBottomLinker.java:73)
	at jdk.internal.dynalink.support.CompositeGuardingDynamicLinker.getGuardedInvocation(CompositeGuardingDynamicLinker.java:124)
	at jdk.internal.dynalink.support.LinkerServicesImpl.getGuardedInvocation(LinkerServicesImpl.java:144)
	at jdk.internal.dynalink.DynamicLinker.relink(DynamicLinker.java:232)
	at jdk.nashorn.internal.scripts.Script$\^eval\_.dnsResolve(<eval>:34)
	at jdk.nashorn.internal.scripts.Script$\^eval\_.FindProxyForURL(<eval>:188)
	at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:502)
	at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:206)
	at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:378)
	at jdk.nashorn.api.scripting.ScriptObjectMirror.callMember(ScriptObjectMirror.java:179)
	at jdk.nashorn.api.scripting.NashornScriptEngine.invokeImpl(NashornScriptEngine.java:508)
	... 32 more

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package testapp;

import java.awt.*;
import java.io.*;
import java.net.*;
import java.util.regex.*;

import javax.swing.*;

public class Testapp {
        public Testapp() {
                JFrame frame = new JFrame("Testapp");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                try {
                        frame.add(new JScrollPane(new JTextArea(Testapp.fetchHtml("http://www.google.de"))));
                }
                catch( Exception e ) {
                        e.printStackTrace();
                }
                frame.pack();
                frame.setVisible(true);
        }


        public static String fetchHtml(String url) throws IOException, URISyntaxException {
                URL url_ = new URL(url);
                try (   InputStream stream = url_.openConnection().getInputStream();
                        InputStreamReader isr = new InputStreamReader(stream);
                        BufferedReader in = new BufferedReader(isr);) {

                        StringBuilder sb = new StringBuilder();
                        String line;
                        while( (line = in.readLine()) != null ) {
                                sb.append(line).append("\n");
                        }
                        return sb.toString();
                }
        }


        public static void main(String[] args) {
                SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                                new Testapp();
                        }
                });
        }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Not using an autoconfig-script and setting a proxy manually works but is not feasible in a corporate environment where more than one proxy must be used for different destinations.


Comments
> Does the fix need to be backported to JDK 7? I think that this issue is specific to 8u/9 (Nashorn) and I wasn't able to reproduce it with 7u (Rhino). > Is not JDK-8061643 duplicate of this issue? I think that these are separate issues: - this issue is about package protection mechanism in Nashorn and it's fixed in deploy code (8u/9) by calling to java code via java.util.function.Function - JDK-8061643 is about missing doPrivileged() wrapping in deploy code - it was exposed after enabling Nashorn/Rhino sandboxing in 14_04 and it's fixed by adding the missing call to doPrivileged()
11-11-2014

reassigning back to deploy to workaround this on deploy side
10-04-2014

Yes, com.sun.deploy.net.proxy is a restricted package. Does the package protection mechanism in Nashorn work for both cases - no-permissions-class and all-permissions-class ? The call to the com.sun.deploy.net.proxy.SunAutoProxyHandler occurs from the deploy code and it's fully privileged code.
08-04-2014

looks like this failure might be caused by a behaviour difference between rhino and nashorn. the source code of the PAC feature (which isn't working in jdk8 now) resides in deploy code deploy/src/common/share/classes/com/sun/deploy/net/proxy/SunAutoProxyHandler.java the deploy binds an instance of SunAutoProxyHandler class to the "obj" key engine.put("obj", this); and executes script engine.eval(autoProxyScript.toString()); the essential part of script to evaluate is below and it calls the java dnsResolve method function dnsResolve(host){ return String(obj.dnsResolve(host)); }; the dnsResolve method exists in SunAutoProxyHandler.java and it's not clear why it can't be found. Transferring to nashorn component for further evaluation. Is this a valid usage of Scripting API? It works in 7u with rhino but fails in 8 with nashorn.
03-04-2014

for some reason the scripting engine can't find SunAutoProxyHandler.dnsResolve function. It works in 7u with rhino but doesn't work in jdk8 with nashorn.
03-04-2014

looks like dupe of https://bugs.openjdk.java.net/browse/JDK-8038984
02-04-2014