Merge remote-tracking branch 'origin/master' into BETA_JAVA16

Change-Id: Ifd127d824103cd7cf94b212c166471d07ff2126f
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java
index 4f3e8fd..b6c7744 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java
@@ -402,6 +402,7 @@
 				cfgs.add(createLaunchConfiguration(jp, "a.b.c.bug484686"));
 				cfgs.add(createLaunchConfiguration(jp, "a.b.c.GenericMethodEntryTest"));
 				cfgs.add(createLaunchConfiguration(jp, "org.eclipse.debug.tests.targets.HcrClass", true));
+				cfgs.add(createLaunchConfiguration(jp, "a.b.c.Bug570988"));
 				loaded15 = true;
 				waitForBuild();
 	        }
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/EvalTestSuite.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/EvalTestSuite.java
index 923bad8..aca0228 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/EvalTestSuite.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/EvalTestSuite.java
@@ -25,6 +25,7 @@
 import org.eclipse.jdt.debug.tests.eval.ByteOperatorsTests;
 import org.eclipse.jdt.debug.tests.eval.CharAssignmentOperatorsTests;
 import org.eclipse.jdt.debug.tests.eval.CharOperatorsTests;
+import org.eclipse.jdt.debug.tests.eval.DebugShellVariableTests;
 import org.eclipse.jdt.debug.tests.eval.DoubleAssignmentOperatorsTests;
 import org.eclipse.jdt.debug.tests.eval.DoubleOperatorsTests;
 import org.eclipse.jdt.debug.tests.eval.FieldValueTests;
@@ -233,6 +234,8 @@
 
 		addTest(new TestSuite(TestsBreakpointConditions.class));
 
+		addTest(new TestSuite(DebugShellVariableTests.class));
+
 	}
 
 	/**
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/DebugShellVariableTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/DebugShellVariableTests.java
new file mode 100644
index 0000000..0b8955b
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/DebugShellVariableTests.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Gayan Perera and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Gayan Perera - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.debug.tests.eval;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.internal.ui.stringsubstitution.SelectedResourceManager;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.contexts.IDebugContextListener;
+import org.eclipse.debug.ui.contexts.IDebugContextProvider;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.debug.core.IJavaThread;
+import org.eclipse.jdt.debug.tests.ui.AbstractDebugUiTests;
+import org.eclipse.jdt.internal.debug.ui.contentassist.CurrentFrameContext;
+import org.eclipse.jdt.internal.debug.ui.contentassist.JavaDebugContentAssistProcessor;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.TextViewer;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+
+public class DebugShellVariableTests extends AbstractDebugUiTests {
+
+	private IJavaThread javaThread;
+	private IDebugContextProvider debugContextProvider;
+
+	public DebugShellVariableTests(String name) {
+		super(name);
+		debugContextProvider = new IDebugContextProvider() {
+			@Override
+			public void removeDebugContextListener(IDebugContextListener listener) {
+			}
+
+			@Override
+			public IWorkbenchPart getPart() {
+				return null;
+			}
+
+			@Override
+			public ISelection getActiveContext() {
+				try {
+					if (javaThread == null) {
+						return StructuredSelection.EMPTY;
+					}
+
+					return new StructuredSelection(javaThread.getTopStackFrame());
+				} catch (DebugException e) {
+					return StructuredSelection.EMPTY;
+				}
+			}
+
+			@Override
+			public void addDebugContextListener(IDebugContextListener listener) {
+			}
+		};
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		registerContextProvider();
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		unregisterContextProvider();
+		super.tearDown();
+	}
+
+	public void testComplete_OnInnerClassTypeVariable_ExpectTypeMemberCompletions() throws Exception {
+		try {
+			debugWithBreakpoint("a.b.c.Bug570988", 27);
+
+			List<ICompletionProposal> proposals = computeCompletionProposals("entry.", 6);
+
+			assertFalse("proposals are empty : ", proposals.isEmpty());
+			assertTrue("expected method[getKey() : String - Entry] is not in proposals :", proposals.stream().anyMatch(p -> p.getDisplayString().equals("getKey() : String - Entry")));
+		} finally {
+			terminateAndRemove(javaThread);
+			removeAllBreakpoints();
+		}
+	}
+
+	public void testComplete_OnGenericClassTypeVariable_ExpectTypeMemberWithCompletionsTypeArguments() throws Exception {
+		try {
+			debugWithBreakpoint("a.b.c.Bug570988", 27);
+
+			List<ICompletionProposal> proposals = computeCompletionProposals("entry.", 6);
+
+			assertFalse("proposals are empty : ", proposals.isEmpty());
+			assertTrue("expected method[getKey() : String - Entry] is not in proposals :", proposals.stream().anyMatch(p -> p.getDisplayString().equals("getKey() : String - Entry")));
+			assertTrue("expected method [getValue() : Long - Entry] is not in proposals :", proposals.stream().anyMatch(p -> p.getDisplayString().equals("getKey() : String - Entry")));
+		} finally {
+			terminateAndRemove(javaThread);
+			removeAllBreakpoints();
+		}
+	}
+
+	private List<ICompletionProposal> computeCompletionProposals(String source, int completionIndex) throws Exception {
+		JavaDebugContentAssistProcessor comp = new JavaDebugContentAssistProcessor(new CurrentFrameContext());
+		ICompletionProposal[] proposals = sync(new Callable<ICompletionProposal[]>() {
+
+			@Override
+			public ICompletionProposal[] call() throws Exception {
+				ITextViewer viewer = new TextViewer(Display.getDefault().getActiveShell(), SWT.NONE);
+				viewer.setDocument(new Document(source));
+				return comp.computeCompletionProposals(viewer, completionIndex);
+			}
+		});
+		assertNull(String.format("Has errors : %s", comp.getErrorMessage()), comp.getErrorMessage());
+		assertNotNull("proposals are null", proposals);
+
+		return Arrays.asList(proposals);
+	}
+
+	private void debugWithBreakpoint(String testClass, int lineNumber) throws Exception {
+		createLineBreakpoint(lineNumber, testClass);
+		javaThread = launchToBreakpoint(testClass);
+		assertNotNull("The program did not suspend", javaThread);
+	}
+
+	@Override
+	protected IJavaProject getProjectContext() {
+		return get15Project();
+	}
+
+	private void registerContextProvider() {
+		IWorkbenchWindow activeWindow = SelectedResourceManager.getDefault().getActiveWindow();
+		assertNotNull("activeWindow is null", activeWindow);
+		DebugUITools.getDebugContextManager().getContextService(activeWindow).addDebugContextProvider(debugContextProvider);
+	}
+
+	private void unregisterContextProvider() {
+		IWorkbenchWindow activeWindow = SelectedResourceManager.getDefault().getActiveWindow();
+		assertNotNull("activeWindow is null", activeWindow);
+		DebugUITools.getDebugContextManager().getContextService(activeWindow).removeDebugContextProvider(debugContextProvider);
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/testsource-j2se-1.5/a/b/c/Bug570988.java b/org.eclipse.jdt.debug.tests/testsource-j2se-1.5/a/b/c/Bug570988.java
new file mode 100644
index 0000000..596c409
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/testsource-j2se-1.5/a/b/c/Bug570988.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Gayan Perera and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Gayan Perera - initial API and implementation
+ *******************************************************************************/
+package a.b.c;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.AbstractMap.SimpleEntry;
+
+public class Bug570988 {
+
+	public static void main(String[] args) {
+		print(new SimpleEntry<String,Long>("Name", 12L));
+	}
+
+	private static void print(Entry<String, Long> entry) {
+		System.out.println(entry.toString());
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/ExpressionInformationControlCreator.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/ExpressionInformationControlCreator.java
index 8365652..3262c54 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/ExpressionInformationControlCreator.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/ExpressionInformationControlCreator.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2008, 2020 IBM Corporation and others.
+ * Copyright (c) 2008, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -14,7 +14,6 @@
 package org.eclipse.jdt.internal.debug.ui;
 
 import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.Platform;
 import org.eclipse.debug.core.model.IVariable;
 import org.eclipse.debug.internal.ui.SWTFactory;
 import org.eclipse.debug.internal.ui.model.elements.ElementContentProvider;
@@ -56,7 +55,6 @@
 import org.eclipse.swt.widgets.Layout;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.TreeItem;
 import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchPartSite;
 
@@ -457,12 +455,6 @@
 			if (input instanceof IVariable) {
 				fVariable = (IVariable) input;
 		        fViewer.setInput(new TreeRoot());
-				// Workaround for empty hover popup dialog due to changed Mac API behaviour
-				if (Platform.OS_MACOSX.equals(Platform.getOS())) {
-					fTree.setItemCount(1);
-					TreeItem item = fTree.getItem(0);
-					item.getText();
-				}
 			}
 		}
 
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/contentassist/CurrentFrameContext.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/contentassist/CurrentFrameContext.java
index 671e782..8b32b6f 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/contentassist/CurrentFrameContext.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/contentassist/CurrentFrameContext.java
@@ -22,6 +22,7 @@
 import org.eclipse.debug.core.model.IVariable;
 import org.eclipse.debug.ui.DebugUITools;
 import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.Signature;
 import org.eclipse.jdt.debug.core.IJavaStackFrame;
 import org.eclipse.jdt.debug.core.IJavaVariable;
 import org.eclipse.jdt.internal.debug.core.JavaDebugUtils;
@@ -79,7 +80,7 @@
                 IJavaVariable var = (IJavaVariable) variables[index];
 				locals[0][i] = resolveVarName(var);
                 try {
-                	locals[1][i] = var.getJavaType().getName();
+					locals[1][i] = Signature.toString(var.getGenericSignature()).replace('/', '.');
                 }
                 catch(DebugException de) {
                 	locals[1][i] = var.getReferenceTypeName();
@@ -110,7 +111,7 @@
 		return name;
 	}
 
-	
+
 	/* (non-Javadoc)
 	 * @see org.eclipse.jdt.internal.debug.ui.contentassist.IJavaDebugContentAssistContext#isStatic()
 	 */
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/display/DisplayView.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/display/DisplayView.java
index 112c84e..0e74cb9 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/display/DisplayView.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/display/DisplayView.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2021 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -421,19 +421,20 @@
 	@Override
 	public <T> T getAdapter(Class<T> required) {
 
-		if (ITextOperationTarget.class.equals(required)) {
-			return (T) fSourceViewer.getTextOperationTarget();
-		}
-
-		if (IFindReplaceTarget.class.equals(required)) {
-			return (T) fSourceViewer.getFindReplaceTarget();
-		}
-
-		if (IDataDisplay.class.equals(required)) {
+		if (fDataDisplay != null && IDataDisplay.class.equals(required)) {
 			return (T) fDataDisplay;
 		}
-		if (ITextViewer.class.equals(required)) {
-			return (T) fSourceViewer;
+		if (fSourceViewer != null) {
+			if (ITextOperationTarget.class.equals(required)) {
+				return (T) fSourceViewer.getTextOperationTarget();
+			}
+
+			if (IFindReplaceTarget.class.equals(required)) {
+				return (T) fSourceViewer.getFindReplaceTarget();
+			}
+			if (ITextViewer.class.equals(required)) {
+				return (T) fSourceViewer;
+			}
 		}
 
 		return super.getAdapter(required);
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaExceptionBreakpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaExceptionBreakpoint.java
index cfc639d..f0fdb42 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaExceptionBreakpoint.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaExceptionBreakpoint.java
@@ -169,9 +169,6 @@
 			final boolean uncaught, final boolean checked, final boolean add,
 			final Map<String, Object> attributes) throws DebugException {
 		IWorkspaceRunnable wr = monitor -> {
-			// create the marker
-			setMarker(resource.createMarker(JAVA_EXCEPTION_BREAKPOINT));
-
 			// add attributes
 			attributes.put(IBreakpoint.ID, getModelIdentifier());
 			attributes.put(TYPE_NAME, exceptionName);
@@ -181,7 +178,8 @@
 			attributes.put(CHECKED, Boolean.valueOf(checked));
 			attributes.put(SUSPEND_POLICY, Integer.valueOf(getDefaultSuspendPolicy()));
 
-			ensureMarker().setAttributes(attributes);
+			// create the marker
+			setMarker(resource.createMarker(JAVA_EXCEPTION_BREAKPOINT, attributes));
 
 			register(add);
 		};
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaMethodBreakpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaMethodBreakpoint.java
index c774669..42f014c 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaMethodBreakpoint.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaMethodBreakpoint.java
@@ -147,9 +147,6 @@
 			final int charStart, final int charEnd, final int hitCount,
 			final boolean register, final Map<String, Object> attributes) throws CoreException {
 		IWorkspaceRunnable wr = monitor -> {
-			// create the marker
-			setMarker(resource.createMarker(JAVA_METHOD_BREAKPOINT));
-
 			// add attributes
 			addLineBreakpointAttributes(attributes, getModelIdentifier(),
 					true, lineNumber, charStart, charEnd);
@@ -160,8 +157,8 @@
 			attributes.put(EXIT, Boolean.valueOf(exit));
 			attributes.put(NATIVE, Boolean.valueOf(nativeOnly));
 			attributes.put(SUSPEND_POLICY, Integer.valueOf(getDefaultSuspendPolicy()));
-			// set attributes
-			ensureMarker().setAttributes(attributes);
+			// create the marker
+			setMarker(resource.createMarker(JAVA_METHOD_BREAKPOINT, attributes));
 			register(register);
 		};
 		run(getMarkerRule(resource), wr);
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaMethodEntryBreakpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaMethodEntryBreakpoint.java
index c1e4760..d4fdea0 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaMethodEntryBreakpoint.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaMethodEntryBreakpoint.java
@@ -77,9 +77,6 @@
 			final int charStart, final int charEnd, final int hitCount,
 			final boolean register, final Map<String, Object> attributes) throws CoreException {
 		IWorkspaceRunnable wr = monitor -> {
-			// create the marker
-			setMarker(resource.createMarker(JAVA_METHOD_ENTRY_BREAKPOINT));
-
 			// add attributes
 			addLineBreakpointAttributes(attributes, getModelIdentifier(),
 					true, lineNumber, charStart, charEnd);
@@ -88,7 +85,8 @@
 			addTypeNameAndHitCount(attributes, typeName, hitCount);
 			// set attributes
 			attributes.put(SUSPEND_POLICY, Integer.valueOf(getDefaultSuspendPolicy()));
-			ensureMarker().setAttributes(attributes);
+			// create the marker
+			setMarker(resource.createMarker(JAVA_METHOD_ENTRY_BREAKPOINT, attributes));
 
 			register(register);
 		};
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaWatchpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaWatchpoint.java
index 24433a9..9d1e61d 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaWatchpoint.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaWatchpoint.java
@@ -111,8 +111,6 @@
 			final int charEnd, final int hitCount, final boolean add,
 			final Map<String, Object> attributes) throws DebugException {
 		IWorkspaceRunnable wr = monitor -> {
-			setMarker(resource.createMarker(JAVA_WATCHPOINT));
-
 			// add attributes
 			addLineBreakpointAttributes(attributes, getModelIdentifier(),
 					true, lineNumber, charStart, charEnd);
@@ -123,8 +121,7 @@
 			// configure the access and modification flags to defaults
 			addDefaultAccessAndModification(attributes);
 
-			// set attributes
-			ensureMarker().setAttributes(attributes);
+			setMarker(resource.createMarker(JAVA_WATCHPOINT, attributes));
 
 			register(add);
 		};
diff --git a/org.eclipse.jdt.launching.javaagent/META-INF/MANIFEST.MF b/org.eclipse.jdt.launching.javaagent/META-INF/MANIFEST.MF
index ee3fd41..1771874 100644
--- a/org.eclipse.jdt.launching.javaagent/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.launching.javaagent/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.launching.javaagent;singleton:=true
-Bundle-Version: 3.9.400.qualifier
+Bundle-Version: 3.9.500.qualifier
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
 Require-Bundle: org.objectweb.asm;bundle-version="[9.0.0,10.0.0)"
diff --git a/org.eclipse.jdt.launching.javaagent/pom.xml b/org.eclipse.jdt.launching.javaagent/pom.xml
index 1cbb83d..a3b58a2 100644
--- a/org.eclipse.jdt.launching.javaagent/pom.xml
+++ b/org.eclipse.jdt.launching.javaagent/pom.xml
@@ -18,13 +18,13 @@
 
   <groupId>org.eclipse.jdt</groupId>
   <artifactId>org.eclipse.jdt.launching.javaagent</artifactId>
-  <version>3.9.400-SNAPSHOT</version>
+  <version>3.9.500-SNAPSHOT</version>
 
   <dependencies>
     <dependency>
       <groupId>org.ow2.asm</groupId>
       <artifactId>asm</artifactId>
-      <version>9.0</version>
+      <version>9.1</version>
     </dependency>
   </dependencies>
 
diff --git a/org.eclipse.jdt.launching.javaagent/src/main/java/org/eclipse/jdt/launching/internal/weaving/ClassfileTransformer.java b/org.eclipse.jdt.launching.javaagent/src/main/java/org/eclipse/jdt/launching/internal/weaving/ClassfileTransformer.java
index c15940f..6e41eba 100644
--- a/org.eclipse.jdt.launching.javaagent/src/main/java/org/eclipse/jdt/launching/internal/weaving/ClassfileTransformer.java
+++ b/org.eclipse.jdt.launching.javaagent/src/main/java/org/eclipse/jdt/launching/internal/weaving/ClassfileTransformer.java
@@ -25,7 +25,7 @@
 	private static final String STRATA_ID = "jdt"; //$NON-NLS-1$
 
 	/** max supported java class format major version, must match {@link #ASM_API} below **/
-	public static final int MAX_CLASS_MAJOR = Opcodes.V16;
+	public static final int MAX_CLASS_MAJOR = Opcodes.V17;
 
 	/** supported ASM API version, must match {@link #MAX_CLASS_MAJOR} above */
 	private static final int ASM_API = Opcodes.ASM9;
diff --git a/org.eclipse.jdt.launching/META-INF/MANIFEST.MF b/org.eclipse.jdt.launching/META-INF/MANIFEST.MF
index 3873dc2..da372e6 100644
--- a/org.eclipse.jdt.launching/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.launching/META-INF/MANIFEST.MF
@@ -14,7 +14,7 @@
  org.eclipse.jdt.launching.sourcelookup,
  org.eclipse.jdt.launching.sourcelookup.advanced,
  org.eclipse.jdt.launching.sourcelookup.containers
-Require-Bundle: org.eclipse.core.resources;bundle-version="[3.5.0,4.0.0)",
+Require-Bundle: org.eclipse.core.resources;bundle-version="[3.14.0,4.0.0)",
  org.eclipse.jdt.core;bundle-version="[3.24.0,4.0.0)",
  org.eclipse.debug.core;bundle-version="[3.17.0,4.0.0)",
  org.eclipse.jdt.debug;bundle-version="[3.17.0,4.0.0)",
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/EECompilationParticipant.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/EECompilationParticipant.java
index 72844b5..de55b1f 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/EECompilationParticipant.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/EECompilationParticipant.java
@@ -17,8 +17,10 @@
 package org.eclipse.jdt.internal.launching;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.eclipse.core.resources.IMarker;
@@ -313,17 +315,11 @@
 	 */
 	private void createJREContainerProblem(IJavaProject javaProject, String message, int severity) {
 		try {
-			IMarker marker = javaProject.getProject().createMarker(JavaRuntime.JRE_CONTAINER_MARKER);
-			marker.setAttributes(
-				new String[] {
-						IMarker.MESSAGE,
-						IMarker.SEVERITY,
-						IMarker.LOCATION},
-					new Object[] {
-						message,
-						Integer.valueOf(severity),
-						LaunchingMessages.LaunchingPlugin_37
-					});
+			Map<String, Object> attributes = Map.of(IMarker.MESSAGE, message, //
+					IMarker.SEVERITY, Integer.valueOf(severity), //
+					IMarker.LOCATION, LaunchingMessages.LaunchingPlugin_37);
+
+			javaProject.getProject().createMarker(JavaRuntime.JRE_CONTAINER_MARKER, attributes);
 		} catch (CoreException e) {
 			return;
 		}
@@ -341,17 +337,12 @@
 	 */
 	private void createProblemMarker(IJavaProject javaProject, String message, int severity, String problemId, String location) {
 		try {
-			IMarker marker = javaProject.getProject().createMarker(problemId);
-			marker.setAttributes(
-					new String[] {
-							IMarker.MESSAGE,
-							IMarker.SEVERITY,
-							IMarker.LOCATION },
-						new Object[] {
-								message,
-								Integer.valueOf(severity),
-								location
-						});
+			Map<String, Object> attributes = new HashMap<>();
+			attributes.put(IMarker.MESSAGE, message);
+			attributes.put(IMarker.SEVERITY, Integer.valueOf(severity));
+			attributes.put(IMarker.LOCATION, location);
+
+			javaProject.getProject().createMarker(problemId, attributes);
 		} catch (CoreException e) {
 			return;
 		}
diff --git a/org.eclipse.jdt.launching/lib/javaagent-shaded.jar b/org.eclipse.jdt.launching/lib/javaagent-shaded.jar
index 8a03ba4..baa63c9 100644
--- a/org.eclipse.jdt.launching/lib/javaagent-shaded.jar
+++ b/org.eclipse.jdt.launching/lib/javaagent-shaded.jar
Binary files differ