diff --git a/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/FirstSourceURLProvider.java b/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/FirstSourceURLProvider.java index c2a3205f2515..bef1bc63eab2 100644 --- a/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/FirstSourceURLProvider.java +++ b/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/FirstSourceURLProvider.java @@ -46,7 +46,10 @@ public class FirstSourceURLProvider extends SourcePathProvider { private static final String[] NO_SOURCE_ROOTS = new String[]{}; - private static final String pathPrefix = "jdk/nashorn/internal/scripts/"; // NOI18N + // prefix for Nashorn built in JDK + private static final String pathPrefixJdk = "jdk/nashorn/internal/scripts/"; // NOI18N + // prefix for external Nashorn + private static final String pathPrefixExt = "org/openjdk/nashorn/internal/scripts/"; // NOI18N private final ContextProvider contextProvider; private SourcePathProvider sourcePath; @@ -56,11 +59,25 @@ public class FirstSourceURLProvider extends SourcePathProvider { public FirstSourceURLProvider(ContextProvider contextProvider) { this.contextProvider = contextProvider; } + + /** + * Returns relative path Nashorn scripts. Either from JDK or from External + * @param relativePath + * @return relative path or null if does match + */ + private String getRelativePath(String relativePath) { + if (relativePath.startsWith(pathPrefixJdk)) { + return relativePath.substring(pathPrefixJdk.length()); + } else if (relativePath.startsWith(pathPrefixExt)) { + return relativePath.substring(pathPrefixExt.length()); + } + return null; + } @Override public String getURL(String relativePath, boolean global) { - if (relativePath.startsWith(pathPrefix)) { - relativePath = relativePath.substring(pathPrefix.length()); + String foundRelativePath = getRelativePath(relativePath); + if (foundRelativePath != null) { synchronized (rootDirsLock) { if (rootDirs == null) { sourcePath = getSourcePathProvider(); @@ -68,7 +85,7 @@ public String getURL(String relativePath, boolean global) { rootDirs = computeModuleRoots(); } for (FileObject root : rootDirs) { - FileObject fo = root.getFileObject(relativePath); + FileObject fo = root.getFileObject(foundRelativePath); if (fo != null) { return fo.toURL().toExternalForm(); } @@ -78,9 +95,17 @@ public String getURL(String relativePath, boolean global) { return null; } + /** + * @param clazz + * @return true if and only if the clazz belongs to Nashorh script (JDK or External) + */ + private boolean isNashornScript(JPDAClassType clazz) { + return clazz.getName().startsWith(JSUtils.NASHORN_SCRIPT_JDK) || clazz.getName().startsWith(JSUtils.NASHORN_SCRIPT_EXT); + } + public String getURL(JPDAClassType clazz, String stratum) { if (!(stratum == null || JSUtils.JS_STRATUM.equals(stratum)) || - !clazz.getName().startsWith(JSUtils.NASHORN_SCRIPT)) { + !isNashornScript(clazz)) { return null; } Source source = Source.getSource(clazz); diff --git a/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/JSUtils.java b/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/JSUtils.java index a8a94fd69bb6..2db5eca22384 100644 --- a/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/JSUtils.java +++ b/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/JSUtils.java @@ -27,7 +27,12 @@ public class JSUtils { public static final String JS_MIME_TYPE = "text/javascript"; // NOI18N public static final String JS_STRATUM = "JS"; // NOI18N - public static final String NASHORN_SCRIPT = "jdk.nashorn.internal.scripts.Script$"; // NOI18N + // Script class for Nashorn built in JDK + public static final String NASHORN_SCRIPT_JDK = "jdk.nashorn.internal.scripts.Script$"; // NOI18N + // avoid API type removed warning, but do not use this constant, use explicitly _JDK or _EXT suffixes + public static final String NASHORN_SCRIPT = NASHORN_SCRIPT_JDK; + // Script class for external Nashorn + public static final String NASHORN_SCRIPT_EXT = "org.openjdk.nashorn.internal.scripts.Script$"; // NOI18N public static final String VAR_THIS = ":this"; // NOI18N public static final String VAR_SCOPE = ":scope"; // NOI18N diff --git a/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/StepIntoJSHandler.java b/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/StepIntoJSHandler.java index f5e42c01b4a4..5b99d84b5f9c 100644 --- a/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/StepIntoJSHandler.java +++ b/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/StepIntoJSHandler.java @@ -64,7 +64,7 @@ @LazyActionsManagerListener.Registration(path="netbeans-JPDASession/Java") public class StepIntoJSHandler extends LazyActionsManagerListener implements PropertyChangeListener { - private static final String SCRIPT_ACCESS_CLASS = "jdk.nashorn.internal.runtime.ScriptFunctionData"; // NOI18N + private static final String SCRIPT_ACCESS_CLASS = "org.openjdk.nashorn.internal.runtime.ScriptFunctionData"; // NOI18N private static final String[] SCRIPT_ACCESS_METHODS = { "invoke", "construct" }; // NOI18N // New notifyInvoke API: private static final String SCRIPT_NOTIFY_INVOKE_METHOD = "notifyInvoke"; // NOI18N @@ -96,7 +96,9 @@ public StepIntoJSHandler(ContextProvider lookupProvider) { scriptAccessBPs[i] = mb; } ScriptInvokeBPListener sibl = new ScriptInvokeBPListener(); - notifyInvokeBP = MethodBreakpoint.create(DebuggerSupport.DEBUGGER_SUPPORT_CLASS, + // try which Nashorn debugger is available + String debugSupportClass = !debugger.getClassesByName(DebuggerSupport.DEBUGGER_SUPPORT_CLASS_JDK).isEmpty() ? DebuggerSupport.DEBUGGER_SUPPORT_CLASS_JDK : DebuggerSupport.DEBUGGER_SUPPORT_CLASS_EXT; + notifyInvokeBP = MethodBreakpoint.create(debugSupportClass, SCRIPT_NOTIFY_INVOKE_METHOD); notifyInvokeBP.setMethodSignature(SCRIPT_NOTIFY_INVOKE_METHOD_SIG); notifyInvokeBP.setHidden(true); diff --git a/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/breakpoints/JSJavaBreakpointsManager.java b/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/breakpoints/JSJavaBreakpointsManager.java index f5f67baaad2e..499b8eddd5df 100644 --- a/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/breakpoints/JSJavaBreakpointsManager.java +++ b/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/breakpoints/JSJavaBreakpointsManager.java @@ -62,6 +62,7 @@ import org.netbeans.modules.debugger.jpda.js.JSUtils; import org.netbeans.modules.debugger.jpda.js.source.ObservableSet; import org.netbeans.modules.debugger.jpda.js.source.Source; +import org.netbeans.modules.debugger.jpda.js.vars.DebuggerSupport; import org.netbeans.modules.javascript2.debug.breakpoints.JSLineBreakpoint; import org.netbeans.spi.debugger.DebuggerServiceRegistration; import org.openide.util.Exceptions; @@ -81,23 +82,25 @@ @DebuggerServiceRegistration(types=LazyDebuggerManagerListener.class) public class JSJavaBreakpointsManager extends DebuggerManagerAdapter { - private static final String NASHORN_CONTEXT_CLASS = "jdk.nashorn.internal.runtime.Context"; // NOI18N + private static final String NASHORN_CONTEXT_CLASS_JDK = "jdk.nashorn.internal.runtime.Context"; // NOI18N + private static final String NASHORN_CONTEXT_CLASS_EXT = "org.openjdk.nashorn.internal.runtime.Context"; // NOI18N private static final String NASHORN_CONTEXT_SOURCE_BIND_METHOD = "cacheClass"; // NOI18N - private static final String NASHORN_SCRIPT_RUNTIME_CLASS = "jdk.nashorn.internal.runtime.ScriptRuntime"; // NOI18N + private static final String NASHORN_SCRIPT_RUNTIME_CLASS_JDK = "jdk.nashorn.internal.runtime.ScriptRuntime"; // NOI18N + private static final String NASHORN_SCRIPT_RUNTIME_CLASS_EXT = "org.openjdk.nashorn.internal.runtime.ScriptRuntime"; // NOI18N private static final String NASHORN_SCRIPT_RUNTIME_DEBUGGER_METHOD = "DEBUGGER"; // NOI18N - private static final String NASHORN_FUNCTION_NODE_CLASS = "jdk.nashorn.internal.ir.FunctionNode"; // NOI18N + private static final String NASHORN_FUNCTION_NODE_CLASS_JDK = "jdk.nashorn.internal.ir.FunctionNode"; // NOI18N + private static final String NASHORN_FUNCTION_NODE_CLASS_EXT = "org.openjdk.nashorn.internal.ir.FunctionNode"; // NOI18N private static final String NASHORN_FUNCTION_NODE_SET_CLASS = "setRootClass"; // NOI18N private static final Logger LOG = Logger.getLogger(JSJavaBreakpointsManager.class.getName()); private final Map scriptHandlers = new HashMap<>(); private final Map> breakpointsByURL = new HashMap<>(); - private ClassLoadUnloadBreakpoint scriptBP; - private MethodBreakpoint sourceBindBP; - private MethodBreakpoint functionClassBP; - private MethodBreakpoint debuggerBP; + private final BreakpointsSet breakpointsLegacyJdk = new BreakpointsSet(); + private final BreakpointsSet breakpointsNashornExt = new BreakpointsSet(); + private BreakpointsSet activeSet = breakpointsLegacyJdk; private final Object sourceBreakpointsInitLock = new Object(); public JSJavaBreakpointsManager() { @@ -106,29 +109,37 @@ public JSJavaBreakpointsManager() { @Override public Breakpoint[] initBreakpoints() { initSourceBreakpoints(); - return new Breakpoint[] { scriptBP, sourceBindBP, functionClassBP, debuggerBP }; + return new Breakpoint[] { + breakpointsLegacyJdk.scriptBP, breakpointsLegacyJdk.sourceBindBP, breakpointsLegacyJdk.functionClassBP, breakpointsLegacyJdk.debuggerBP, + breakpointsNashornExt.scriptBP, breakpointsNashornExt.sourceBindBP, breakpointsNashornExt.functionClassBP, breakpointsNashornExt.debuggerBP + }; } private void initSourceBreakpoints() { synchronized (sourceBreakpointsInitLock) { - if (scriptBP == null) { - scriptBP = ClassLoadUnloadBreakpoint.create(JSUtils.NASHORN_SCRIPT+"*", - false, - ClassLoadUnloadBreakpoint.TYPE_CLASS_LOADED); - scriptBP.setHidden(true); - scriptBP.setSuspend(EventRequest.SUSPEND_NONE); + if (breakpointsLegacyJdk.scriptBP == null) { + for (int i=0; i < 2; i++) { + BreakpointsSet set = (i == 0) ? breakpointsLegacyJdk : breakpointsNashornExt; + boolean jdk = (set == breakpointsLegacyJdk); - sourceBindBP = MethodBreakpoint.create(NASHORN_CONTEXT_CLASS, NASHORN_CONTEXT_SOURCE_BIND_METHOD); - sourceBindBP.setHidden(true); - sourceBindBP.setSuspend(EventRequest.SUSPEND_EVENT_THREAD); - - functionClassBP = MethodBreakpoint.create(NASHORN_FUNCTION_NODE_CLASS, NASHORN_FUNCTION_NODE_SET_CLASS); - functionClassBP.setHidden(true); - functionClassBP.setSuspend(EventRequest.SUSPEND_EVENT_THREAD); - - debuggerBP = MethodBreakpoint.create(NASHORN_SCRIPT_RUNTIME_CLASS, NASHORN_SCRIPT_RUNTIME_DEBUGGER_METHOD); - debuggerBP.setHidden(true); - debuggerBP.setSuspend(EventRequest.SUSPEND_EVENT_THREAD); + set.scriptBP = ClassLoadUnloadBreakpoint.create((jdk ? JSUtils.NASHORN_SCRIPT_JDK : JSUtils.NASHORN_SCRIPT_EXT)+"*", + false, + ClassLoadUnloadBreakpoint.TYPE_CLASS_LOADED); + set.scriptBP.setHidden(true); + set.scriptBP.setSuspend(EventRequest.SUSPEND_NONE); + + set.sourceBindBP = MethodBreakpoint.create(jdk ? NASHORN_CONTEXT_CLASS_JDK : NASHORN_CONTEXT_CLASS_EXT, NASHORN_CONTEXT_SOURCE_BIND_METHOD); + set.sourceBindBP.setHidden(true); + set.sourceBindBP.setSuspend(EventRequest.SUSPEND_EVENT_THREAD); + + set.functionClassBP = MethodBreakpoint.create(jdk ? NASHORN_FUNCTION_NODE_CLASS_JDK : NASHORN_FUNCTION_NODE_CLASS_EXT, NASHORN_FUNCTION_NODE_SET_CLASS); + set.functionClassBP.setHidden(true); + set.functionClassBP.setSuspend(EventRequest.SUSPEND_EVENT_THREAD); + + set.debuggerBP = MethodBreakpoint.create(jdk ? NASHORN_SCRIPT_RUNTIME_CLASS_JDK : NASHORN_SCRIPT_RUNTIME_CLASS_EXT, NASHORN_SCRIPT_RUNTIME_DEBUGGER_METHOD); + set.debuggerBP.setHidden(true); + set.debuggerBP.setSuspend(EventRequest.SUSPEND_EVENT_THREAD); + } } } } @@ -200,10 +211,18 @@ public void engineAdded(DebuggerEngine engine) { } initSourceBreakpoints(); ScriptsHandler sh = new ScriptsHandler(debugger); - scriptBP.addJPDABreakpointListener(sh); - sourceBindBP.addJPDABreakpointListener(sh); - functionClassBP.addJPDABreakpointListener(sh); - debuggerBP.addJPDABreakpointListener(sh); + List classesByName = DebuggerSupport.getSupportDebuggerClasses(debugger); + if (classesByName.isEmpty()) { + return ; + } + JPDAClassType contextClass = classesByName.get(0); + boolean legacyJdk = DebuggerSupport.isLegacyNashorn(contextClass); + activeSet = legacyJdk ? breakpointsLegacyJdk : breakpointsNashornExt; + + activeSet.scriptBP.addJPDABreakpointListener(sh); + activeSet.sourceBindBP.addJPDABreakpointListener(sh); + activeSet.functionClassBP.addJPDABreakpointListener(sh); + activeSet.debuggerBP.addJPDABreakpointListener(sh); synchronized (scriptHandlers) { scriptHandlers.put(debugger, sh); } @@ -220,15 +239,22 @@ public void engineRemoved(DebuggerEngine engine) { sh = scriptHandlers.remove(debugger); } if (sh != null) { - scriptBP.removeJPDABreakpointListener(sh); - sourceBindBP.removeJPDABreakpointListener(sh); - functionClassBP.removeJPDABreakpointListener(sh); - debuggerBP.removeJPDABreakpointListener(sh); - scriptBP.enable(); + activeSet.scriptBP.removeJPDABreakpointListener(sh); + activeSet.sourceBindBP.removeJPDABreakpointListener(sh); + activeSet.functionClassBP.removeJPDABreakpointListener(sh); + activeSet.debuggerBP.removeJPDABreakpointListener(sh); + activeSet.scriptBP.enable(); sh.destroy(); } } - + + private final class BreakpointsSet { + ClassLoadUnloadBreakpoint scriptBP; + MethodBreakpoint sourceBindBP; + MethodBreakpoint functionClassBP; + MethodBreakpoint debuggerBP; + } + private final class ScriptsHandler implements JPDABreakpointListener { private final JPDADebugger debugger; @@ -261,7 +287,7 @@ public void breakpointReached(JPDABreakpointEvent event) { return ; } Object eventSource = event.getSource(); - if (scriptBP == eventSource) { + if (activeSet.scriptBP == eventSource) { // A new script class is loaded. Variable scriptClass = event.getVariable(); if (!(scriptClass instanceof ClassVariable)) { @@ -287,7 +313,7 @@ public void breakpointReached(JPDABreakpointEvent event) { scriptAccessBreakpoints.put(scriptMethodBP, scriptType); } } - } else if (sourceBindBP == eventSource) { + } else if (activeSet.sourceBindBP == eventSource) { Variable sourceVar = null; Variable scriptClass = null; try { @@ -326,10 +352,10 @@ public void breakpointReached(JPDABreakpointEvent event) { } if (!isSourceBind) { isSourceBind = true; - scriptBP.disable(); + activeSet.scriptBP.disable(); } } - } else if (functionClassBP == eventSource) { + } else if (activeSet.functionClassBP == eventSource) { Variable rootClass = null; Variable sourceVar = null; try { @@ -366,7 +392,7 @@ public void breakpointReached(JPDABreakpointEvent event) { source.addFunctionClass((ClassVariable) rootClass); } } - } else if (debuggerBP == eventSource) { + } else if (activeSet.debuggerBP == eventSource) { JPDAStep step = debugger.createJPDAStep(JPDAStep.STEP_LINE, JPDAStep.STEP_INTO); step.addStep(event.getThread()); } else { @@ -398,11 +424,12 @@ public void propertyChange(PropertyChangeEvent evt) { }); return ; } - List classesByName = debugger.getClassesByName(NASHORN_CONTEXT_CLASS); + List classesByName = debugger.getClassesByName((activeSet == breakpointsLegacyJdk) ? NASHORN_CONTEXT_CLASS_JDK : NASHORN_CONTEXT_CLASS_EXT); if (classesByName.isEmpty()) { return ; } JPDAClassType contextClass = classesByName.get(0); + boolean jdk = DebuggerSupport.isLegacyNashorn(contextClass); List contextInstances = contextClass.getInstances(0); if (contextInstances.isEmpty()) { return ; @@ -415,7 +442,7 @@ public void propertyChange(PropertyChangeEvent evt) { } // We need to suspend the app to be able to invoke methods: - final MethodBreakpoint inNashorn = MethodBreakpoint.create(NASHORN_FUNCTION_NODE_CLASS, "*"); + final MethodBreakpoint inNashorn = MethodBreakpoint.create(jdk ? NASHORN_FUNCTION_NODE_CLASS_JDK : NASHORN_FUNCTION_NODE_CLASS_EXT, "*"); final AtomicBoolean retrieved = new AtomicBoolean(false); inNashorn.addJPDABreakpointListener(new JPDABreakpointListener() { @Override diff --git a/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/source/Source.java b/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/source/Source.java index 9ceaa2476e8f..493a29bc21f6 100644 --- a/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/source/Source.java +++ b/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/source/Source.java @@ -50,7 +50,8 @@ public final class Source { private static final Logger LOG = Logger.getLogger(Source.class.getName()); - private static final String SOURCE_CLASS = "jdk.nashorn.internal.runtime.Source"; // NOI18N + private static final String SOURCE_CLASS_JDK = "jdk.nashorn.internal.runtime.Source"; // NOI18N + private static final String SOURCE_CLASS_EXT = "org.openjdk.nashorn.internal.runtime.Source"; // NOI18N private static final String SOURCE_FIELD = "source"; // NOI18N private static final String SOURCE_VAR_NAME = "name"; // NOI18N @@ -227,7 +228,7 @@ private static ObjectVariable getSourceVar(JPDADebugger debugger, JPDAClassType for (Field sf : staticFields) { if (sf instanceof ObjectVariable && SOURCE_FIELD.equals(sf.getName()) && - SOURCE_CLASS.equals(sf.getType())) { + (SOURCE_CLASS_JDK.equals(sf.getType()) || SOURCE_CLASS_EXT.equals(sf.getType()))) { return (ObjectVariable) sf; } diff --git a/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/vars/DebuggerSupport.java b/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/vars/DebuggerSupport.java index da2aa78c9541..2ade4f5ddc18 100644 --- a/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/vars/DebuggerSupport.java +++ b/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/vars/DebuggerSupport.java @@ -50,26 +50,39 @@ * @author Martin */ public final class DebuggerSupport { - - public static final String DEBUGGER_SUPPORT_CLASS = "jdk.nashorn.internal.runtime.DebuggerSupport"; // NOI18N - private static final String DEBUGGER_SUPPORT_VALUE_DESC_CLASS = "jdk.nashorn.internal.runtime.DebuggerSupport$DebuggerValueDesc"; // NOI18N - private static final String CONTEXT_CLASS = "jdk.nashorn.internal.runtime.Context"; // NOI18N + + public static final String DEBUGGER_SUPPORT_CLASS_JDK = "jdk.nashorn.internal.runtime.DebuggerSupport"; // NOI18N + // avoid API type removed warning, but do not use this constant, use explicitly _JDK or _EXT suffixes + public static final String DEBUGGER_SUPPORT_CLASS = DEBUGGER_SUPPORT_CLASS_JDK; + private static final String DEBUGGER_SUPPORT_VALUE_DESC_CLASS_JDK = "jdk.nashorn.internal.runtime.DebuggerSupport$DebuggerValueDesc"; // NOI18N + private static final String CONTEXT_CLASS_JDK = "jdk.nashorn.internal.runtime.Context"; // NOI18N + + public static final String DEBUGGER_SUPPORT_CLASS_EXT = "org.openjdk.nashorn.internal.runtime.DebuggerSupport"; // NOI18N + private static final String DEBUGGER_SUPPORT_VALUE_DESC_CLASS_EXT = "org.openjdk.nashorn.internal.runtime.DebuggerSupport$DebuggerValueDesc"; // NOI18N + private static final String CONTEXT_CLASS_EXT = "org.openjdk.nashorn.internal.runtime.Context"; // NOI18N private static final String METHOD_VALUE_INFO = "valueInfo"; // NOI18N - private static final String SIGNAT_VALUE_INFO = "(Ljava/lang/String;Ljava/lang/Object;Z)Ljdk/nashorn/internal/runtime/DebuggerSupport$DebuggerValueDesc;"; // NOI18N + private static final String SIGNAT_VALUE_INFO_JDK = "(Ljava/lang/String;Ljava/lang/Object;Z)Ljdk/nashorn/internal/runtime/DebuggerSupport$DebuggerValueDesc;"; // NOI18N + private static final String SIGNAT_VALUE_INFO_EXT = "(Ljava/lang/String;Ljava/lang/Object;Z)Lorg/openjdk/nashorn/internal/runtime/DebuggerSupport$DebuggerValueDesc;"; // NOI18N private static final String METHOD_VALUE_INFOS = "valueInfos"; // NOI18N - private static final String SIGNAT_VALUE_INFOS = "(Ljava/lang/Object;Z)[Ljdk/nashorn/internal/runtime/DebuggerSupport$DebuggerValueDesc;"; // NOI18N + private static final String SIGNAT_VALUE_INFOS_JDK = "(Ljava/lang/Object;Z)[Ljdk/nashorn/internal/runtime/DebuggerSupport$DebuggerValueDesc;"; // NOI18N + private static final String SIGNAT_VALUE_INFOS_EXT = "(Ljava/lang/Object;Z)[Lorg/openjdk/nashorn/internal/runtime/DebuggerSupport$DebuggerValueDesc;"; // NOI18N private static final String METHOD_EVAL = "eval"; // NOI18N - private static final String SIGNAT_EVAL = "(Ljdk/nashorn/internal/runtime/ScriptObject;Ljava/lang/Object;Ljava/lang/String;Z)Ljava/lang/Object;"; // NOI18N + private static final String SIGNAT_EVAL_JDK = "(Ljdk/nashorn/internal/runtime/ScriptObject;Ljava/lang/Object;Ljava/lang/String;Z)Ljava/lang/Object;"; // NOI18N + private static final String SIGNAT_EVAL_EXT = "(Lorg/openjdk/nashorn/internal/runtime/ScriptObject;Ljava/lang/Object;Ljava/lang/String;Z)Ljava/lang/Object;"; // NOI18N private static final String METHOD_FROM_CLASS = "fromClass"; // NOI18N - private static final String SIGNAT_FROM_CLASS = "(Ljava/lang/Class;)Ljdk/nashorn/internal/runtime/Context;"; // NOI18N + private static final String SIGNAT_FROM_CLASS_JDK = "(Ljava/lang/Class;)Ljdk/nashorn/internal/runtime/Context;"; // NOI18N + private static final String SIGNAT_FROM_CLASS_EXT = "(Ljava/lang/Class;)Lorg/openjdk/nashorn/internal/runtime/Context;"; // NOI18N private static final String METHOD_CONTEXT_EVAL= "eval"; // NOI18N - private static final String SIGNAT_CONTEXT_EVAL= "(Ljdk/nashorn/internal/runtime/ScriptObject;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"; // NOI18N - private static final String SIGNAT_CONTEXT_EVAL_OLD = "(Ljdk/nashorn/internal/runtime/ScriptObject;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;Z)Ljava/lang/Object;"; // NOI18N + private static final String SIGNAT_CONTEXT_EVAL_JDK= "(Ljdk/nashorn/internal/runtime/ScriptObject;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"; // NOI18N + private static final String SIGNAT_CONTEXT_EVAL_OLD_JDK = "(Ljdk/nashorn/internal/runtime/ScriptObject;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;Z)Ljava/lang/Object;"; // NOI18N + private static final String SIGNAT_CONTEXT_EVAL_EXT= "(Lorg/openjdk/nashorn/internal/runtime/ScriptObject;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"; // NOI18N + private static final String SIGNAT_CONTEXT_EVAL_OLD_EXT = "(Lorg/openjdk/nashorn/internal/runtime/ScriptObject;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;Z)Ljava/lang/Object;"; // NOI18N private static final String METHOD_VALUE_AS_STRING = "valueAsString"; // NOI18N private static final String SIGNAT_VALUE_AS_STRING = "(Ljava/lang/Object;)Ljava/lang/String;"; // NOI18N private static final String METHOD_SOURCE_INFO = "getSourceInfo"; // NOI18N - private static final String SIGNAT_SOURCE_INFO = "(Ljava/lang/Class;)Ljdk/nashorn/internal/runtime/DebuggerSupport$SourceInfo;"; // NOI18N + private static final String SIGNAT_SOURCE_INFO_JDK = "(Ljava/lang/Class;)Ljdk/nashorn/internal/runtime/DebuggerSupport$SourceInfo;"; // NOI18N + private static final String SIGNAT_SOURCE_INFO_EXT = "(Ljava/lang/Class;)Lorg/openjdk/nashorn/internal/runtime/DebuggerSupport$SourceInfo;"; // NOI18N private static final String FIELD_DESC_VALUE_AS_STRING = "valueAsString"; // NOI18N private static final String FIELD_DESC_KEY = "key"; // NOI18N @@ -86,7 +99,7 @@ public final class DebuggerSupport { private DebuggerSupport() {} static Variable getValueInfoDesc(JPDADebugger debugger, String name, Variable value, boolean all) { - List supportClasses = debugger.getClassesByName(DEBUGGER_SUPPORT_CLASS); + List supportClasses = getSupportDebuggerClasses(debugger); if (supportClasses.isEmpty()) { return null; } @@ -96,7 +109,7 @@ static Variable getValueInfoDesc(JPDADebugger debugger, String name, Variable va args[0] = debugger.createMirrorVar(name); args[1] = value; args[2] = debugger.createMirrorVar(all, true); - return supportClass.invokeMethod(METHOD_VALUE_INFO, SIGNAT_VALUE_INFO, args); + return supportClass.invokeMethod(METHOD_VALUE_INFO, isLegacyNashorn(supportClass) ? SIGNAT_VALUE_INFO_JDK : SIGNAT_VALUE_INFO_EXT, args); } catch (InvalidObjectException | InvalidExpressionException iex) { return null; } catch (NoSuchMethodException nsmex) { @@ -132,7 +145,7 @@ static boolean isDescriptionExpandable(Variable descVar) { } static Variable[] getValueInfos(JPDADebugger debugger, Variable scope, boolean all) { - List supportClasses = debugger.getClassesByName(DEBUGGER_SUPPORT_CLASS); + List supportClasses = getSupportDebuggerClasses(debugger); if (supportClasses.isEmpty()) { return null; } @@ -141,7 +154,7 @@ static Variable[] getValueInfos(JPDADebugger debugger, Variable scope, boolean a try { args[0] = scope; args[1] = debugger.createMirrorVar(all, true); - ObjectVariable infosVar = (ObjectVariable) supportClass.invokeMethod(METHOD_VALUE_INFOS, SIGNAT_VALUE_INFOS, args); + ObjectVariable infosVar = (ObjectVariable) supportClass.invokeMethod(METHOD_VALUE_INFOS, isLegacyNashorn(supportClass) ? SIGNAT_VALUE_INFOS_JDK : SIGNAT_VALUE_INFOS_EXT, args); return infosVar.getFields(0, Integer.MAX_VALUE); } catch (InvalidObjectException ioex) { return null; @@ -154,14 +167,14 @@ static Variable[] getValueInfos(JPDADebugger debugger, Variable scope, boolean a } public static boolean hasSourceInfo(JPDADebugger debugger) { - List supportClasses = debugger.getClassesByName(DEBUGGER_SUPPORT_CLASS); + List supportClasses = getSupportDebuggerClasses(debugger); if (supportClasses.isEmpty()) { return false; } JPDAClassType supportClass = supportClasses.get(0); try { ReferenceType supportType = (ReferenceType) supportClass.getClass().getMethod("getType").invoke(supportClass); - Method getSourceInfoMethod = ((ClassType) supportType).concreteMethodByName(METHOD_SOURCE_INFO, SIGNAT_SOURCE_INFO); + Method getSourceInfoMethod = ((ClassType) supportType).concreteMethodByName(METHOD_SOURCE_INFO, isLegacyNashorn(supportClass) ? SIGNAT_SOURCE_INFO_JDK : SIGNAT_SOURCE_INFO_EXT); return getSourceInfoMethod != null; } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { Exceptions.printStackTrace(ex); @@ -172,13 +185,13 @@ public static boolean hasSourceInfo(JPDADebugger debugger) { } public static Variable getSourceInfo(JPDADebugger debugger, JPDAClassType classType) { - List supportClasses = debugger.getClassesByName(DEBUGGER_SUPPORT_CLASS); + List supportClasses = getSupportDebuggerClasses(debugger); if (supportClasses.isEmpty()) { return null; } JPDAClassType supportClass = supportClasses.get(0); try { - Variable sourceInfo = supportClass.invokeMethod(METHOD_SOURCE_INFO, SIGNAT_SOURCE_INFO, new Variable[] { classType.classObject() }); + Variable sourceInfo = supportClass.invokeMethod(METHOD_SOURCE_INFO, isLegacyNashorn(supportClass) ? SIGNAT_SOURCE_INFO_JDK : SIGNAT_SOURCE_INFO_EXT, new Variable[] { classType.classObject() }); return sourceInfo; } catch (NoSuchMethodException | InvalidExpressionException ex) { return null; @@ -208,7 +221,7 @@ public static Variable evaluate(JPDADebugger debugger, CallStackFrame frame, Str } private static Variable doEvaluate(JPDADebugger debugger, CallStackFrame frame, String expression, ObjectVariable contextVar) throws InvalidExpressionException { - List supportClasses = debugger.getClassesByName(DEBUGGER_SUPPORT_CLASS); + List supportClasses = getSupportDebuggerClasses(debugger); if (supportClasses.isEmpty()) { return null; } @@ -244,14 +257,14 @@ private static Variable doEvaluate(JPDADebugger debugger, CallStackFrame frame, // Evaluate on the current class' context: Source source = Source.getSource(frame); JPDAClassType sourceClassType = source.getClassType(); + final boolean legacyNashorn = isLegacyNashorn(supportClass); // Call Context.fromClass(clazz): - List contextClassesByName = debugger.getClassesByName(CONTEXT_CLASS); + List contextClassesByName = debugger.getClassesByName(legacyNashorn ? CONTEXT_CLASS_JDK : CONTEXT_CLASS_EXT); JPDAClassType contextClass = contextClassesByName.get(0); Variable contextObj = null; try { - contextObj = contextClass.invokeMethod( - METHOD_FROM_CLASS, - SIGNAT_FROM_CLASS, + contextObj = contextClass.invokeMethod(METHOD_FROM_CLASS, + legacyNashorn ? SIGNAT_FROM_CLASS_JDK : SIGNAT_FROM_CLASS_EXT, new Variable[] { sourceClassType.classObject() }); } catch (NoSuchMethodException nsmex) { Exceptions.printStackTrace(nsmex); @@ -270,9 +283,8 @@ private static Variable doEvaluate(JPDADebugger debugger, CallStackFrame frame, Exceptions.printStackTrace(ioex); throw new InvalidExpressionException(ioex); } - return ((ObjectVariable) contextObj).invokeMethod( - METHOD_CONTEXT_EVAL, - SIGNAT_CONTEXT_EVAL, + return ((ObjectVariable) contextObj).invokeMethod(METHOD_CONTEXT_EVAL, + legacyNashorn ? SIGNAT_CONTEXT_EVAL_JDK : SIGNAT_CONTEXT_EVAL_EXT, args); } catch (NoSuchMethodException nsmex) { oldEval = true; @@ -293,9 +305,8 @@ private static Variable doEvaluate(JPDADebugger debugger, CallStackFrame frame, Exceptions.printStackTrace(ioex); throw new InvalidExpressionException(ioex); } - return ((ObjectVariable) contextObj).invokeMethod( - METHOD_CONTEXT_EVAL, - SIGNAT_CONTEXT_EVAL_OLD, + return ((ObjectVariable) contextObj).invokeMethod(METHOD_CONTEXT_EVAL, + legacyNashorn ? SIGNAT_CONTEXT_EVAL_OLD_JDK : SIGNAT_CONTEXT_EVAL_OLD_EXT, args); } catch (NoSuchMethodException nsmex) { Exceptions.printStackTrace(nsmex); @@ -309,7 +320,7 @@ private static Variable doEvaluate(JPDADebugger debugger, CallStackFrame frame, args[1] = contextVar; args[2] = debugger.createMirrorVar(expression); args[3] = debugger.createMirrorVar(false, true); - return supportClass.invokeMethod(METHOD_EVAL, SIGNAT_EVAL, args); + return supportClass.invokeMethod(METHOD_EVAL, legacyNashorn ? SIGNAT_EVAL_JDK : SIGNAT_EVAL_EXT, args); } catch (InvalidObjectException ioex) { Exceptions.printStackTrace(ioex); throw new InvalidExpressionException(ioex); @@ -334,11 +345,33 @@ private static boolean isOldEval(JPDADebugger debugger) { private static void setOldEval(JPDADebugger debugger) { hasOldEval.add(new WeakReference<>(debugger)); } + + /** + * Tries to find Nashorn debugger classes either in built-in JDK or external Nashorn + * @param debugger + * @return debugger classes list (or empty list) + */ + public static List getSupportDebuggerClasses(JPDADebugger debugger) { + List supportClasses = debugger.getClassesByName(DEBUGGER_SUPPORT_CLASS_JDK); + if (supportClasses.isEmpty()) { + // if not in JDK, look for External Nashorn + supportClasses = debugger.getClassesByName(DEBUGGER_SUPPORT_CLASS_EXT); + } + return supportClasses; + } + + /** + * @param classType returned from getSupportDebuggerClasses() + * @return true when classTYpe belongs to the legacy JDK Nashorn, false otherwise + */ + public static boolean isLegacyNashorn(JPDAClassType classType) { + return classType.getName().startsWith("jdk.nashorn.internal."); + } public static String getVarValue(JPDADebugger debugger, Variable var) { if (var instanceof ObjectVariable) { ObjectVariable ov = (ObjectVariable) var; - List supportClasses = debugger.getClassesByName(DEBUGGER_SUPPORT_CLASS); + List supportClasses = getSupportDebuggerClasses(debugger); JPDAClassType ct; if (supportClasses.isEmpty() || ((ct = ov.getClassType()) != null && String.class.getCanonicalName().equals(ct.getName()))) { @@ -375,7 +408,7 @@ public static String getVarValue(JPDADebugger debugger, Variable var) { } public static Variable getVarStringValueAsVar(JPDADebugger debugger, ObjectVariable ov) { - List supportClasses = debugger.getClassesByName(DEBUGGER_SUPPORT_CLASS); + List supportClasses = getSupportDebuggerClasses(debugger); if (supportClasses.isEmpty()) { return ov; } diff --git a/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/vars/JSVariable.java b/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/vars/JSVariable.java index c3244e0dea86..78139c4d034d 100644 --- a/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/vars/JSVariable.java +++ b/java/debugger.jpda.js/src/org/netbeans/modules/debugger/jpda/js/vars/JSVariable.java @@ -52,7 +52,7 @@ protected JSVariable(JPDADebugger debugger, Variable valueInfoDesc) { JPDAClassType classType = ((ObjectVariable) valueObjectVar).getClassType(); if (classType != null) { String className = classType.getName(); - if (!className.startsWith("jdk.nashorn") && !String.class.getName().equals(className)) { // NOI18N + if (!className.startsWith("jdk.nashorn") && !className.startsWith("org.openjdk.nashorn") && !String.class.getName().equals(className)) { // NOI18N // Not a Nashorn's script class valueObject = (ObjectVariable) valueObjectVar; } @@ -101,7 +101,8 @@ public static JSVariable createIfScriptObject(JPDADebugger debugger, ObjectVaria if (classType == null) { return null; } - boolean isScript = classType.isInstanceOf("jdk.nashorn.internal.runtime.ScriptObject"); // NOI18N + boolean isScript = classType.isInstanceOf("jdk.nashorn.internal.runtime.ScriptObject") || // NOI18N + classType.isInstanceOf("org.openjdk.nashorn.internal.runtime.ScriptObject"); // NOI18N if (!isScript) { return null; } diff --git a/java/debugger.jpda.jsui/src/org/netbeans/modules/debugger/jpda/jsui/frames/models/DebuggingJSActionsProvider.java b/java/debugger.jpda.jsui/src/org/netbeans/modules/debugger/jpda/jsui/frames/models/DebuggingJSActionsProvider.java index 3babd65fa280..0389712ef6b4 100644 --- a/java/debugger.jpda.jsui/src/org/netbeans/modules/debugger/jpda/jsui/frames/models/DebuggingJSActionsProvider.java +++ b/java/debugger.jpda.jsui/src/org/netbeans/modules/debugger/jpda/jsui/frames/models/DebuggingJSActionsProvider.java @@ -242,8 +242,10 @@ void appendStackInfo(StringBuffer frameStr, JPDAThread t) { JSStackFrame jsframe = (JSStackFrame) ch; frame = jsframe.getJavaFrame(); String cName = frame.getClassName(); - if (cName.startsWith(JSUtils.NASHORN_SCRIPT)) { - cName = cName.substring(JSUtils.NASHORN_SCRIPT.length()); + if (cName.startsWith(JSUtils.NASHORN_SCRIPT_JDK)) { + cName = cName.substring(JSUtils.NASHORN_SCRIPT_JDK.length()); + } else if (cName.startsWith(JSUtils.NASHORN_SCRIPT_EXT)) { + cName = cName.substring(JSUtils.NASHORN_SCRIPT_EXT.length()); } frameStr.append("\tat "); frameStr.append(cName); diff --git a/java/debugger.jpda.jsui/src/org/netbeans/modules/debugger/jpda/jsui/frames/models/DebuggingJSNodeModel.java b/java/debugger.jpda.jsui/src/org/netbeans/modules/debugger/jpda/jsui/frames/models/DebuggingJSNodeModel.java index e06bcf7d4bba..8940857ea0fb 100644 --- a/java/debugger.jpda.jsui/src/org/netbeans/modules/debugger/jpda/jsui/frames/models/DebuggingJSNodeModel.java +++ b/java/debugger.jpda.jsui/src/org/netbeans/modules/debugger/jpda/jsui/frames/models/DebuggingJSNodeModel.java @@ -108,7 +108,13 @@ public String getDisplayName(NodeModel original, Object node) throws UnknownType CallStackFrame javaFrame = ((JSStackFrame) node).getJavaFrame(); descr = original.getDisplayName(javaFrame); //System.out.println("ORIG descr = '"+descr+"'"); - int i = descr.indexOf(JSUtils.NASHORN_SCRIPT); + String nashornScriptClass = JSUtils.NASHORN_SCRIPT_JDK; + int i = descr.indexOf(nashornScriptClass); + if (i < 0) { + // if Legacy JDK not found, search for external Nashorn + nashornScriptClass = JSUtils.NASHORN_SCRIPT_EXT; + i = descr.indexOf(nashornScriptClass); + } int i2 = 0; if (i < 0) { if (descr.startsWith(SCRIPT_CLASS_PREFIX)) { @@ -122,7 +128,7 @@ public String getDisplayName(NodeModel original, Object node) throws UnknownType } } } else { - i2 = i + JSUtils.NASHORN_SCRIPT.length(); + i2 = i + nashornScriptClass.length(); } if (i >= 0) { descr = descr.substring(0, i) + descr.substring(i2); diff --git a/java/debugger.jpda.jsui/src/org/netbeans/modules/debugger/jpda/jsui/frames/models/DebuggingJSTreeExpansionModelFilter.java b/java/debugger.jpda.jsui/src/org/netbeans/modules/debugger/jpda/jsui/frames/models/DebuggingJSTreeExpansionModelFilter.java index 1c2c8b24e471..1b1e08cd3579 100644 --- a/java/debugger.jpda.jsui/src/org/netbeans/modules/debugger/jpda/jsui/frames/models/DebuggingJSTreeExpansionModelFilter.java +++ b/java/debugger.jpda.jsui/src/org/netbeans/modules/debugger/jpda/jsui/frames/models/DebuggingJSTreeExpansionModelFilter.java @@ -136,7 +136,7 @@ public void propertyChange(PropertyChangeEvent evt) { } private void currentStackFrameChanged(CallStackFrame csf) { - if (csf != null && csf.getClassName().startsWith(JSUtils.NASHORN_SCRIPT)) { + if (csf != null && (csf.getClassName().startsWith(JSUtils.NASHORN_SCRIPT_JDK) || csf.getClassName().startsWith(JSUtils.NASHORN_SCRIPT_EXT))) { JPDAThread thread = csf.getThread(); suspendedNashornThread = new WeakReference<>(thread); try { diff --git a/java/debugger.jpda.jsui/src/org/netbeans/modules/debugger/jpda/jsui/frames/models/DebuggingJSTreeModel.java b/java/debugger.jpda.jsui/src/org/netbeans/modules/debugger/jpda/jsui/frames/models/DebuggingJSTreeModel.java index 4a05e9da8486..11aeaf2a2e63 100644 --- a/java/debugger.jpda.jsui/src/org/netbeans/modules/debugger/jpda/jsui/frames/models/DebuggingJSTreeModel.java +++ b/java/debugger.jpda.jsui/src/org/netbeans/modules/debugger/jpda/jsui/frames/models/DebuggingJSTreeModel.java @@ -67,7 +67,7 @@ static Object[] createChildrenWithJSStack(Object[] children) { Object ch = children[i]; if (ch instanceof CallStackFrame) { CallStackFrame csf = (CallStackFrame) ch; - if (csf.getClassName().startsWith(JSUtils.NASHORN_SCRIPT)) { + if (csf.getClassName().startsWith(JSUtils.NASHORN_SCRIPT_JDK) || csf.getClassName().startsWith(JSUtils.NASHORN_SCRIPT_EXT)) { if (!isJSStack) { Object[] children2 = new Object[children.length]; System.arraycopy(children, 0, children2, 0, children.length); diff --git a/java/debugger.jpda/src/org/netbeans/modules/debugger/jpda/models/CallStackFrameImpl.java b/java/debugger.jpda/src/org/netbeans/modules/debugger/jpda/models/CallStackFrameImpl.java index 608c08e89b40..66f281f79cdf 100644 --- a/java/debugger.jpda/src/org/netbeans/modules/debugger/jpda/models/CallStackFrameImpl.java +++ b/java/debugger.jpda/src/org/netbeans/modules/debugger/jpda/models/CallStackFrameImpl.java @@ -314,7 +314,9 @@ private synchronized void initStrata() { } else { // Check Nashorn: String sourcePath = getSourcePath(null); - if (sourcePath.startsWith("jdk/nashorn/internal/scripts/") || // NOI18N + if (sourcePath.startsWith("org/openjdk/nashorn/internal/scripts/") || // NOI18N + sourcePath.startsWith("org\\openjdk\\nashorn\\internal\\scripts\\") || // NOI18N + sourcePath.startsWith("jdk/nashorn/internal/scripts/") || // NOI18N sourcePath.startsWith("jdk\\nashorn\\internal\\scripts\\")) { // NOI18N s = "JS"; // NOI18N as = Collections.singletonList(s);