Index: src/org/netbeans/modules/debugger/jpda/breakpoints/BreakpointImpl.java =================================================================== RCS file: /cvs/debuggerjpda/src/org/netbeans/modules/debugger/jpda/breakpoints/BreakpointImpl.java,v retrieving revision 1.26 diff -u -r1.26 BreakpointImpl.java --- src/org/netbeans/modules/debugger/jpda/breakpoints/BreakpointImpl.java 27 Apr 2006 15:29:28 -0000 1.26 +++ src/org/netbeans/modules/debugger/jpda/breakpoints/BreakpointImpl.java 3 May 2006 16:27:02 -0000 @@ -93,9 +93,13 @@ (getDebugger ().getState () == JPDADebugger.STATE_DISCONNECTED) ) return; removeAllEventRequests (); - if (breakpoint.isEnabled ()) { + if (breakpoint.isEnabled () && isEnabled()) { setRequests (); } + } + + protected boolean isEnabled() { + return true; } public void propertyChange (PropertyChangeEvent evt) { Index: src/org/netbeans/modules/debugger/jpda/breakpoints/BreakpointsReader.java =================================================================== RCS file: /cvs/debuggerjpda/src/org/netbeans/modules/debugger/jpda/breakpoints/BreakpointsReader.java,v retrieving revision 1.1 diff -u -r1.1 BreakpointsReader.java --- src/org/netbeans/modules/debugger/jpda/breakpoints/BreakpointsReader.java 8 Dec 2005 15:55:43 -0000 1.1 +++ src/org/netbeans/modules/debugger/jpda/breakpoints/BreakpointsReader.java 3 May 2006 16:27:02 -0000 @@ -7,7 +7,7 @@ * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original - * Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun * Microsystems, Inc. All Rights Reserved. */ @@ -34,6 +34,7 @@ public class BreakpointsReader implements Properties.Reader { private Map cachedClassNames = new WeakHashMap(); + private Map cachedSourceRoots = new WeakHashMap(); public String [] getSupportedClassNames () { @@ -46,6 +47,10 @@ return (String) cachedClassNames.get(b); } + synchronized String findCachedSourceRoot(JPDABreakpoint b) { + return (String) cachedSourceRoots.get(b); + } + void storeCachedClassName(JPDABreakpoint b, String className) { synchronized (this) { cachedClassNames.put(b, className); @@ -53,6 +58,13 @@ PersistenceManager.storeBreakpoints(); } + void storeCachedSourceRoot(JPDABreakpoint b, String sourceRoot) { + synchronized (this) { + cachedSourceRoots.put(b, sourceRoot); + } + PersistenceManager.storeBreakpoints(); + } + public Object read (String typeID, Properties properties) { JPDABreakpoint b = null; // Read both LineBreakpoint and LineBreakpoint$LineBreakpointImpl @@ -67,6 +79,7 @@ ); synchronized (this) { cachedClassNames.put(lb, properties.getString("className", null)); + cachedSourceRoots.put(lb, properties.getString("sourceRoot", null)); } b = lb; } @@ -96,6 +109,9 @@ MethodBreakpoint.TYPE_METHOD_ENTRY ) ); + synchronized (this) { + cachedSourceRoots.put(mb, properties.getString("sourceRoot", null)); + } b = mb; } if (typeID.equals (ClassLoadUnloadBreakpoint.class.getName ())) { @@ -117,6 +133,9 @@ new String [0] ) ); + synchronized (this) { + cachedSourceRoots.put(cb, properties.getString("sourceRoot", null)); + } b = cb; } if (typeID.equals (ExceptionBreakpoint.class.getName ())) { @@ -133,6 +152,9 @@ eb.setCondition ( properties.getString (ExceptionBreakpoint.PROP_CONDITION, "") ); + synchronized (this) { + cachedSourceRoots.put(eb, properties.getString("sourceRoot", null)); + } b = eb; } if (typeID.equals (FieldBreakpoint.class.getName ())) { @@ -147,6 +169,9 @@ fb.setCondition ( properties.getString (FieldBreakpoint.PROP_CONDITION, "") ); + synchronized (this) { + cachedSourceRoots.put(fb, properties.getString("sourceRoot", null)); + } b = fb; } if (typeID.equals (ThreadBreakpoint.class.getName ())) { @@ -204,8 +229,8 @@ LineBreakpoint.PROP_CONDITION, lb.getCondition () ); - String className = findCachedClassName(lb); - properties.setString("className", className); + properties.setString("className", findCachedClassName(lb)); + properties.setString("sourceRoot", findCachedSourceRoot(lb)); return; } else if (object instanceof MethodBreakpoint) { @@ -230,6 +255,7 @@ MethodBreakpoint.PROP_BREAKPOINT_TYPE, mb.getBreakpointType () ); + properties.setString("sourceRoot", findCachedSourceRoot(mb)); return; } else if (object instanceof ClassLoadUnloadBreakpoint) { @@ -246,6 +272,7 @@ ClassLoadUnloadBreakpoint.PROP_BREAKPOINT_TYPE, cb.getBreakpointType () ); + properties.setString("sourceRoot", findCachedSourceRoot(cb)); return; } else if (object instanceof ExceptionBreakpoint) { @@ -262,6 +289,7 @@ ExceptionBreakpoint.PROP_CONDITION, eb.getCondition () ); + properties.setString("sourceRoot", findCachedSourceRoot(eb)); return; } else if (object instanceof FieldBreakpoint) { @@ -282,6 +310,7 @@ FieldBreakpoint.PROP_BREAKPOINT_TYPE, fb.getBreakpointType () ); + properties.setString("sourceRoot", findCachedSourceRoot(fb)); return; } else if (object instanceof ThreadBreakpoint) { Index: src/org/netbeans/modules/debugger/jpda/breakpoints/ClassBasedBreakpoint.java =================================================================== RCS file: /cvs/debuggerjpda/src/org/netbeans/modules/debugger/jpda/breakpoints/ClassBasedBreakpoint.java,v retrieving revision 1.11 diff -u -r1.11 ClassBasedBreakpoint.java --- src/org/netbeans/modules/debugger/jpda/breakpoints/ClassBasedBreakpoint.java 8 Dec 2005 15:55:43 -0000 1.11 +++ src/org/netbeans/modules/debugger/jpda/breakpoints/ClassBasedBreakpoint.java 3 May 2006 16:27:02 -0000 @@ -7,7 +7,7 @@ * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original - * Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun * Microsystems, Inc. All Rights Reserved. */ @@ -21,6 +21,8 @@ import com.sun.jdi.request.ClassPrepareRequest; import com.sun.jdi.request.ClassUnloadRequest; import com.sun.jdi.VirtualMachine; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.util.Iterator; import org.netbeans.api.debugger.jpda.ClassLoadUnloadBreakpoint; @@ -28,6 +30,8 @@ import org.netbeans.api.debugger.jpda.JPDABreakpoint; import org.netbeans.api.debugger.Session; import org.netbeans.modules.debugger.jpda.JPDADebuggerImpl; +import org.netbeans.spi.debugger.jpda.SourcePathProvider; +import org.openide.util.WeakListeners; /** * Implementation of breakpoint on method. @@ -36,6 +40,10 @@ */ public abstract class ClassBasedBreakpoint extends BreakpointImpl { + private String sourceRoot; + private final Object SOURCE_ROOT_LOCK = new Object(); + private SourceRootsChangedListener srChListener; + private static boolean verbose = System.getProperty ("netbeans.debugger.breakpoints") != null; @@ -56,6 +64,42 @@ super (breakpoint, reader, debugger, session); } + protected final void setSourceRoot(String sourceRoot) { + synchronized (SOURCE_ROOT_LOCK) { + this.sourceRoot = sourceRoot; + if (sourceRoot != null && srChListener == null) { + srChListener = new SourceRootsChangedListener(); + getDebugger().getEngineContext().addPropertyChangeListener( + WeakListeners.propertyChange(srChListener, + getDebugger().getEngineContext())); + } else if (sourceRoot == null) { + srChListener = null; // release the listener + } + } + } + + protected final String getSourceRoot() { + synchronized (SOURCE_ROOT_LOCK) { + return sourceRoot; + } + } + + protected boolean isEnabled() { + synchronized (SOURCE_ROOT_LOCK) { + String sourceRoot = getSourceRoot(); + if (sourceRoot == null) { + return true; + } + String[] sourceRoots = getDebugger().getEngineContext().getSourceRoots(); + for (int i = 0; i < sourceRoots.length; i++) { + if (sourceRoot.equals(sourceRoots[i])) { + return true; + } + } + return false; + } + } + protected void setClassRequests ( String[] classFilters, String[] classExclusionFilters, @@ -153,5 +197,16 @@ protected void classLoaded (ReferenceType referenceType) {} protected void classUnloaded (String className) {} + + + private class SourceRootsChangedListener implements PropertyChangeListener { + + public void propertyChange(PropertyChangeEvent evt) { + if (SourcePathProvider.PROP_SOURCE_ROOTS.equals(evt.getPropertyName())) { + update(); + } + } + + } } Index: src/org/netbeans/modules/debugger/jpda/breakpoints/LineBreakpointImpl.java =================================================================== RCS file: /cvs/debuggerjpda/src/org/netbeans/modules/debugger/jpda/breakpoints/LineBreakpointImpl.java,v retrieving revision 1.25 diff -u -r1.25 LineBreakpointImpl.java --- src/org/netbeans/modules/debugger/jpda/breakpoints/LineBreakpointImpl.java 8 Dec 2005 15:55:44 -0000 1.25 +++ src/org/netbeans/modules/debugger/jpda/breakpoints/LineBreakpointImpl.java 3 May 2006 16:27:02 -0000 @@ -7,7 +7,7 @@ * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original - * Code is Sun Microsystems, Inc. Portions Copyright 1997-2000 Sun + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun * Microsystems, Inc. All Rights Reserved. */ @@ -56,7 +56,6 @@ private LineBreakpoint breakpoint; - private SourcePath sourcePath; private int lineNumber; private BreakpointsReader reader; @@ -71,8 +70,8 @@ super (breakpoint, reader, debugger, session); this.reader = reader; this.breakpoint = breakpoint; - this.sourcePath = sourcePath; lineNumber = breakpoint.getLineNumber (); + setSourceRoot(sourcePath.getSourceRoot(breakpoint.getURL())); set (); } Index: test/unit/src/org/netbeans/api/debugger/jpda/LineBreakpointTest.java =================================================================== RCS file: /cvs/debuggerjpda/test/unit/src/org/netbeans/api/debugger/jpda/LineBreakpointTest.java,v retrieving revision 1.10 diff -u -r1.10 LineBreakpointTest.java --- test/unit/src/org/netbeans/api/debugger/jpda/LineBreakpointTest.java 4 Jan 2006 14:16:53 -0000 1.10 +++ test/unit/src/org/netbeans/api/debugger/jpda/LineBreakpointTest.java 3 May 2006 16:27:02 -0000 @@ -230,6 +230,119 @@ } + /** + * Tests debugger's ability to make difference between different projects + * with the same classes while getting the locations during class-loaded event. + * + * 1. The user creates 2 classes: ${test.dir.src}/.../LineBreakpointApp.java + * and ${test.dir.src_2}/.../LineBreakpointApp.java + * 2. Then set a breakpoint in ${test.dir.src_2}/.../LineBreakpointApp.java. + * + * Debugger should stop _only_ in the second project. If debugger stopped in + * the first one, then assertion violation would arise because of source path + * equality test. + */ + public void testBreakpointUnambiguity1 () throws Exception { + try { + LineBreakpoint lb1 = LineBreakpoint.create (TEST_APP, 33); +// lb1.setSourceRoot(System.getProperty ("test.dir.src")); + DebuggerManager dm = DebuggerManager.getDebuggerManager (); + dm.addBreakpoint (lb1); + + TestBreakpointListener tb1 = new TestBreakpointListener (lb1); + lb1.addJPDABreakpointListener (tb1); + + support = JPDASupport.attach ( + "org.netbeans.api.debugger.jpda.testapps.LineBreakpointApp" + ); + JPDADebugger debugger = support.getDebugger(); + + support.waitState (JPDADebugger.STATE_STOPPED); // breakpoint hit, the source root is correct + assertEquals ( + "Debugger stopped at wrong line", + lb1.getLineNumber (), + debugger.getCurrentCallStackFrame ().getLineNumber (null) + ); + + tb1.checkResult (); + support.doContinue(); + support.waitState (JPDADebugger.STATE_DISCONNECTED); + dm.removeBreakpoint (lb1); + support.doFinish (); + /* + // Second run - BP should not be hit with a different source root - viz testBreakpointUnambiguity2() + support = null; + lb1 = LineBreakpoint.create (TEST_APP, 33); + lb1.setSourceRoot(System.getProperty ("test.dir.src")+"_2"); + dm = DebuggerManager.getDebuggerManager (); + dm.addBreakpoint (lb1); + + tb1 = new TestBreakpointListener (lb1); + lb1.addJPDABreakpointListener (tb1); + + support = JPDASupport.attach ( + "org.netbeans.api.debugger.jpda.testapps.LineBreakpointApp" + ); + debugger = support.getDebugger(); + + support.waitState (JPDADebugger.STATE_STOPPED); // Stopped or disconnected + assertEquals( + "Debugger should not stop on BP with faked source root", + debugger.getState(), + JPDADebugger.STATE_DISCONNECTED + ); + tb1.checkNotNotified(); + dm.removeBreakpoint (lb1); + */ + } finally { + if (support != null) support.doFinish (); + } + } + + /** + * Tests debugger's ability to make difference between different projects + * with the same classes while getting the locations during class-loaded event. + * + * 1. The user creates 2 classes: ${test.dir.src}/.../LineBreakpointApp.java + * and ${test.dir.src_2}/.../LineBreakpointApp.java + * 2. Then set a breakpoint in ${test.dir.src_2}/.../LineBreakpointApp.java. + * + * Debugger should stop _only_ in the second project. If debugger stopped in + * the first one, then assertion violation would arise because of source path + * equality test. + */ + public void testBreakpointUnambiguity2 () throws Exception { + try { + LineBreakpoint lb1 = LineBreakpoint.create( + System.getProperty("user.home") + java.io.File.separator + + //System.getProperty ("test.dir.src") + + "org/netbeans/api/debugger/jpda/testapps/LineBreakpointApp.java", 33); + //lb1.setSourceRoot(System.getProperty ("test.dir.src") + "_2"); + DebuggerManager dm = DebuggerManager.getDebuggerManager (); + dm.addBreakpoint (lb1); + + TestBreakpointListener tb1 = new TestBreakpointListener (lb1); + lb1.addJPDABreakpointListener (tb1); + + support = JPDASupport.attach ( + "org.netbeans.api.debugger.jpda.testapps.LineBreakpointApp" + ); + JPDADebugger debugger = support.getDebugger(); + + support.waitState (JPDADebugger.STATE_STOPPED); // Stopped or disconnected + assertEquals( + "Debugger should not stop on BP with faked source root", + debugger.getState(), + JPDADebugger.STATE_DISCONNECTED + ); + + tb1.checkNotNotified(); + dm.removeBreakpoint (lb1); + } finally { + if (support != null) support.doFinish (); + } + } + // innerclasses ............................................................ private class TestBreakpointListener implements JPDABreakpointListener { @@ -296,6 +409,16 @@ } throw new AssertionError ( "Breakpoint was not hit (listener was not notified) " + ln + ); + } + if (failure != null) throw failure; + } + + public void checkNotNotified() { + if (event != null) { + JPDAThread t = event.getThread(); + throw new AssertionError ( + "Breakpoint was hit (listener was notified) in thread " + t ); } if (failure != null) throw failure; Index: src/org/netbeans/modules/debugger/jpda/SourcePath.java =================================================================== RCS file: /cvs/debuggerjpda/src/org/netbeans/modules/debugger/jpda/SourcePath.java,v retrieving revision 1.5 diff -u -r1.5 SourcePath.java --- src/org/netbeans/modules/debugger/jpda/SourcePath.java 8 Jan 2006 22:39:49 -0000 1.5 +++ src/org/netbeans/modules/debugger/jpda/SourcePath.java 3 May 2006 16:27:02 -0000 @@ -83,6 +83,17 @@ return getContext ().getRelativePath (url, directorySeparator, includeExtension); } + + /** + * Returns the source root (if any) for given url. + * + * @param url a url of resource file + * + * @return the source root or null when no source root was found. + */ + public String getSourceRoot(String url) { + return getContext().getSourceRoot(url); + } /** * Translates a relative path ("java/lang/Thread.java") to url @@ -359,7 +370,15 @@ includeExtension ); } - + + public String getSourceRoot(String url) { + String sourceRoot = cp1.getSourceRoot(url); + if (sourceRoot == null) { + sourceRoot = cp2.getSourceRoot(url); + } + return sourceRoot; + } + public String[] getSourceRoots () { String[] fs1 = cp1.getSourceRoots (); String[] fs2 = cp2.getSourceRoots (); Index: api/src/org/netbeans/spi/debugger/jpda/SourcePathProvider.java =================================================================== RCS file: /cvs/debuggerjpda/api/src/org/netbeans/spi/debugger/jpda/SourcePathProvider.java,v retrieving revision 1.2 diff -u -r1.2 SourcePathProvider.java --- api/src/org/netbeans/spi/debugger/jpda/SourcePathProvider.java 18 Oct 2004 14:57:49 -0000 1.2 +++ api/src/org/netbeans/spi/debugger/jpda/SourcePathProvider.java 3 May 2006 16:27:02 -0000 @@ -7,7 +7,7 @@ * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original - * Code is Sun Micro//S ystems, Inc. Portions Copyright 1997-2001 Sun + * Code is Sun Micro//S ystems, Inc. Portions Copyright 1997-2006 Sun * Micro//S ystems, Inc. All Rights Reserved. */ package org.netbeans.spi.debugger.jpda; @@ -60,6 +60,18 @@ */ public abstract String getURL (String relativePath, boolean global); + /** + * Returns the source root (if any) for given url. + * + * @param url a url of resource file + * + * @return the source root or null when no source root was found. + * @since 2.6 + */ + public String getSourceRoot(String url) { + return null; + } + /** * Returns array of source roots. */ Index: ant/src/org/netbeans/modules/debugger/projects/SourcePathProviderImpl.java =================================================================== RCS file: /cvs/debuggerjpda/ant/src/org/netbeans/modules/debugger/projects/SourcePathProviderImpl.java,v retrieving revision 1.12 diff -u -r1.12 SourcePathProviderImpl.java --- ant/src/org/netbeans/modules/debugger/projects/SourcePathProviderImpl.java 2 Mar 2005 15:46:19 -0000 1.12 +++ ant/src/org/netbeans/modules/debugger/projects/SourcePathProviderImpl.java 3 May 2006 16:27:03 -0000 @@ -7,7 +7,7 @@ * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original - * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun * Microsystems, Inc. All Rights Reserved. */ @@ -184,6 +184,37 @@ directorySeparator, includeExtension ); + } + + /** + * Returns the source root (if any) for given url. + * + * @param url a url of resource file + * + * @return the source root or null when no source root was found. + */ + public String getSourceRoot(String url) { + Iterator it = GlobalPathRegistry.getDefault().getSourceRoots().iterator(); + while (it.hasNext()) { + FileObject fileObject = (FileObject) it.next (); + try { + String rootURL = fileObject.getURL().toString(); + if (url.startsWith(rootURL)) { + File f = null; + if (fileObject.getFileSystem () instanceof JarFileSystem) + f = ((JarFileSystem) fileObject.getFileSystem ()). + getJarFile (); + else + f = FileUtil.toFile (fileObject); + if (f != null) { + return f.getAbsolutePath (); + } + } + } catch (FileStateInvalidException ex) { + // Invalid source root - skip + } + } + return null; // not found } /** Index: test/unit/src/org/netbeans/api/debugger/jpda/test/TestEngineContextProvider.java =================================================================== RCS file: /cvs/debuggerjpda/test/unit/src/org/netbeans/api/debugger/jpda/test/TestEngineContextProvider.java,v retrieving revision 1.8 diff -u -r1.8 TestEngineContextProvider.java --- test/unit/src/org/netbeans/api/debugger/jpda/test/TestEngineContextProvider.java 4 Jun 2005 05:16:04 -0000 1.8 +++ test/unit/src/org/netbeans/api/debugger/jpda/test/TestEngineContextProvider.java 3 May 2006 16:27:03 -0000 @@ -7,7 +7,7 @@ * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original - * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun * Microsystems, Inc. All Rights Reserved. */ @@ -23,6 +23,10 @@ import java.net.URL; import java.net.MalformedURLException; import java.io.File; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileStateInvalidException; +import org.openide.filesystems.FileUtil; +import org.openide.filesystems.JarFileSystem; /** @@ -33,14 +37,20 @@ public class TestEngineContextProvider extends SourcePathProvider { private String sourceRoot = System.getProperty ("test.dir.src"); + private String home = System.getProperty("user.home"); private String[] originalSourceRoots = new String[] { - sourceRoot + sourceRoot, home }; private PropertyChangeSupport pcs = new PropertyChangeSupport(this); public TestEngineContextProvider (ContextProvider ctxProvider) { // this.session = (Session) ctxProvider.lookupFirst (null, Session.class); + for (int i = 0; i < originalSourceRoots.length; i++) { + while (originalSourceRoots[i].endsWith(File.separator)) { + originalSourceRoots[i] = originalSourceRoots[i].substring(0, originalSourceRoots[i].length() - 1); + } + } } /** @@ -108,6 +118,38 @@ public void setSourceRoots (String[] sourceRoots) { } + public String getSourceRoot(String url) { + for (int i = 0; i < originalSourceRoots.length; i++) { + String sourceRoot = originalSourceRoots[i]; + FileObject fileObject = FileUtil.toFileObject(new File(sourceRoot)); + String rootURL; + try { + if (fileObject == null) { + rootURL = sourceRoot; + } else { + rootURL = fileObject.getURL().toString(); + } + if (url.startsWith(rootURL)) { + File f = null; + if (fileObject != null) { + if (fileObject.getFileSystem () instanceof JarFileSystem) + f = ((JarFileSystem) fileObject.getFileSystem ()).getJarFile (); + else + f = FileUtil.toFile (fileObject); + } else { + f = new File(sourceRoot); + } + if (f != null) { + return f.getAbsolutePath (); + } + } + } catch (FileStateInvalidException ex) { + // Invalid source root - skip + } + } + return null; // not found + } + /** * Adds property change listener. * Index: api/apichanges.xml =================================================================== RCS file: /cvs/debuggerjpda/api/apichanges.xml,v retrieving revision 1.12 diff -u -r1.12 apichanges.xml --- api/apichanges.xml 3 Nov 2005 11:34:45 -0000 1.12 +++ api/apichanges.xml 3 May 2006 16:27:03 -0000 @@ -365,6 +365,23 @@ + + + Added getSourceRoot() method to SourcePathProvider class + + + + + +

+ Retrieves a source root for a given URL. This is necessary to + match breakpoint locations with the sources selected fopr debugging. + It returns null by default. +

+
+ + +
Index: api/manifest.mf =================================================================== RCS file: /cvs/debuggerjpda/api/manifest.mf,v retrieving revision 1.16 diff -u -r1.16 manifest.mf --- api/manifest.mf 12 Dec 2005 15:37:49 -0000 1.16 +++ api/manifest.mf 3 May 2006 16:27:03 -0000 @@ -1,6 +1,6 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.api.debugger.jpda/2 OpenIDE-Module-Localizing-Bundle: org/netbeans/api/debugger/jpda/Bundle.properties -OpenIDE-Module-Specification-Version: 2.5 +OpenIDE-Module-Specification-Version: 2.6 OpenIDE-Module-Package-Dependencies: com.sun.jdi[VirtualMachineManager]