Merge pull request #3139 from sdedic/bugfix/javacompiler-phase

Get elements resolved before working with types.
diff --git a/ide/projectapi/src/org/netbeans/modules/projectapi/LazyLookup.java b/ide/projectapi/src/org/netbeans/modules/projectapi/LazyLookup.java
new file mode 100644
index 0000000..fd57a98
--- /dev/null
+++ b/ide/projectapi/src/org/netbeans/modules/projectapi/LazyLookup.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.projectapi;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executor;
+import java.util.logging.Level;
+import org.openide.filesystems.FileObject;
+import org.openide.util.Exceptions;
+import org.openide.util.Lookup;
+import org.openide.util.lookup.Lookups;
+import org.openide.util.lookup.ProxyLookup;
+
+final class LazyLookup extends ProxyLookup {
+    private final Map<String, Object> attrs;
+    private final Lookup lkp;
+    private Collection<String> serviceNames;
+    final Thread[] LOCK = {null};
+
+    public LazyLookup(Map<String, Object> attrs, Lookup lkp) {
+        this.attrs = attrs;
+        this.lkp = lkp;
+        this.serviceNames = Arrays.asList(((String) attrs.get("service")).split(",")); // NOI18N
+    }
+
+    @Override
+    protected void beforeLookup(Template<?> template) {
+        class NotifyLater implements Executor {
+            private List<Runnable> pending = new ArrayList<>();
+            @Override
+            public void execute(Runnable command) {
+                pending.add(command);
+            }
+            
+            public void deliverPending() {
+                List<Runnable> notify = pending;
+                pending = null;
+                for (Runnable r : notify) {
+                    r.run();
+                }
+            }
+        }
+        LazyLookupProviders.safeToLoad(this.lkp);
+        Class<?> service = template.getType();
+        NotifyLater later = null;
+        synchronized (LOCK) {
+            for (;;) {
+                if (serviceNames == null || !serviceNames.contains(service.getName())) {
+                    return;
+                }
+                if (LOCK[0] == null) {
+                    break;
+                }
+                if (LOCK[0] == Thread.currentThread()) {
+                    return;
+                }
+                try {
+                    LOCK.wait();
+                } catch (InterruptedException ex) {
+                    LazyLookupProviders.LOG.log(Level.INFO, null, ex);
+                }
+            }
+            LOCK[0] = Thread.currentThread();
+            LOCK.notifyAll();
+        }
+        try {
+            Object instance = LazyLookupProviders.loadPSPInstance((String) attrs.get("class"), (String) attrs.get("method"), lkp); // NOI18N
+            if (!service.isInstance(instance)) {
+                // JRE #6456938: Class.cast currently throws an exception without details.
+                throw new ClassCastException("Instance of " + instance.getClass() + " unassignable to " + service);
+            }
+            setLookups(later = new NotifyLater(), Lookups.singleton(instance));
+            synchronized (LOCK) {
+                serviceNames = null;
+                LOCK.notifyAll();
+            }
+        } catch (Exception x) {
+            Exceptions.attachMessage(x, "while loading from " + attrs);
+            Exceptions.printStackTrace(x);
+        } finally {
+            synchronized (LOCK) {
+                LOCK[0] = null;
+                LOCK.notifyAll();
+            }
+            if (later != null) {
+                later.deliverPending();
+            }
+        }
+    }
+
+    boolean isInitializing() {
+        return LOCK[0] != null;
+    }
+    
+    @Override
+    @SuppressWarnings(value = "element-type-mismatch")
+    public String toString() {
+        return "LazyLookupProviders.LookupProvider[service=" + attrs.get("service") + ", class=" + attrs.get("class") + ", orig=" + attrs.get(FileObject.class) + "]";
+    }
+
+}
diff --git a/ide/projectapi/src/org/netbeans/modules/projectapi/LazyLookupProviders.java b/ide/projectapi/src/org/netbeans/modules/projectapi/LazyLookupProviders.java
index 6b62c69..74bfc11 100644
--- a/ide/projectapi/src/org/netbeans/modules/projectapi/LazyLookupProviders.java
+++ b/ide/projectapi/src/org/netbeans/modules/projectapi/LazyLookupProviders.java
@@ -23,7 +23,6 @@
 import java.lang.reflect.Member;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
@@ -37,13 +36,9 @@
 import org.netbeans.spi.project.LookupMerger;
 import org.netbeans.spi.project.LookupProvider;
 import org.netbeans.spi.project.ProjectServiceProvider;
-import org.openide.filesystems.FileObject;
 import org.openide.util.ChangeSupport;
 import org.openide.util.Exceptions;
 import org.openide.util.Lookup;
-import org.openide.util.Lookup.Template;
-import org.openide.util.lookup.Lookups;
-import org.openide.util.lookup.ProxyLookup;
 
 /**
  * Factory methods for lazy {@link LookupProvider} registration.
@@ -52,7 +47,7 @@
 
     private LazyLookupProviders() {}
 
-    private static final Logger LOG = Logger.getLogger(LazyLookupProviders.class.getName());
+    static final Logger LOG = Logger.getLogger(LazyLookupProviders.class.getName());
     private static final Map<Lookup,ThreadLocal<Member>> INSIDE_LOAD = new WeakHashMap<Lookup,ThreadLocal<Member>>();
     private static final Collection<Member> WARNED = Collections.synchronizedSet(new HashSet<Member>());
 
@@ -62,97 +57,39 @@
     public static LookupProvider forProjectServiceProvider(final Map<String,Object> attrs) throws ClassNotFoundException {
         class Prov implements LookupProvider {
             @Override
-            public Lookup createAdditionalLookup(final Lookup lkp) {
-                final Lookup result =  new ProxyLookup() {
-                    Collection<String> serviceNames = Arrays.asList(((String) attrs.get("service")).split(",")); // NOI18N
-                    final Thread[] LOCK = { null };
-                    @Override protected void beforeLookup(Template<?> template) {
-                        safeToLoad();
-                        Class<?> service = template.getType();
-                        synchronized (LOCK) {
-                            for (;;) {
-                                if (serviceNames == null || !serviceNames.contains(service.getName())) {
-                                    return;
-                                }
-                                if (LOCK[0] == null) {
-                                    break;
-                                }
-                                if (LOCK[0] == Thread.currentThread()) {
-                                    return;
-                                }
-                                try {
-                                    LOCK.wait();
-                                } catch (InterruptedException ex) {
-                                    LOG.log(Level.INFO, null, ex);
-                                }
-                            }
-                            LOCK[0] = Thread.currentThread();
-                        }
-                        try {
-                            Object instance = loadPSPInstance((String) attrs.get("class"), (String) attrs.get("method"), lkp); // NOI18N
-                            if (!service.isInstance(instance)) {
-                                // JRE #6456938: Class.cast currently throws an exception without details.
-                                throw new ClassCastException("Instance of " + instance.getClass() + " unassignable to " + service);
-                            }
-                            setLookups(Lookups.singleton(instance));
-                            synchronized (LOCK) {
-                                serviceNames = null;
-                            }
-                        } catch (Exception x) {
-                            Exceptions.attachMessage(x, "while loading from " + attrs);
-                            Exceptions.printStackTrace(x);
-                        } finally {
-                            synchronized (LOCK) {
-                                LOCK[0] = null;
-                                LOCK.notifyAll();
-                            }
-                        }
-                    }
-                    private void safeToLoad() {
-                        ThreadLocal<Member> memberRef;
-                        synchronized (INSIDE_LOAD) {
-                            memberRef = INSIDE_LOAD.get(lkp);
-                        }
-                        if (memberRef == null) {
-                            return;
-                        }
-                        Member member = memberRef.get();
-                        if (member != null && WARNED.add(member)) {
-                            LOG.log(Level.WARNING, null, new IllegalStateException("may not call Project.getLookup().lookup(...) inside " + member.getName() + " registered under @ProjectServiceProvider"));
-                        }
-                    }
-
-                    @Override
-                    public String toString() {
-                        return Prov.this.toString();
-                    }
-                };
+            public Lookup createAdditionalLookup(Lookup lkp) {
+                LazyLookup result = new LazyLookup(attrs, lkp);
                 if (LOG.isLoggable(Level.FINE)) {
                     LOG.log(
-                        Level.FINE,
-                        "Additional lookup created: {0} service class: {1} for base lookup: {2}",   //NOI18N
-                        new Object[]{
+                            Level.FINE,
+                            "Additional lookup created: {0} service class: {1} for base lookup: {2}", //NOI18N
+                            new Object[]{
                             System.identityHashCode(result),
-                            attrs.get("class"),
-                            System.identityHashCode(lkp)
-                        });
+                                attrs.get("class"),
+                                System.identityHashCode(lkp)
+                            });
                 }
                 return result;
             }
-            
-            @Override
-            @SuppressWarnings("element-type-mismatch")
-            public String toString() {
-                return "LazyLookupProviders.LookupProvider[service=" + 
-                    attrs.get("service") + 
-                    ", class=" + attrs.get("class") + 
-                    ", orig=" + attrs.get(FileObject.class) + 
-                    "]";
-            }
-        };
+        }
         return new Prov();
     }
-    private static Object loadPSPInstance(String implName, String methodName, Lookup lkp) throws Exception {
+
+    static void safeToLoad(Lookup lkp) {
+        ThreadLocal<Member> memberRef;
+        synchronized (LazyLookupProviders.INSIDE_LOAD) {
+            memberRef = LazyLookupProviders.INSIDE_LOAD.get(lkp);
+        }
+        if (memberRef == null) {
+            return;
+        }
+        Member member = memberRef.get();
+        if (member != null && LazyLookupProviders.WARNED.add(member)) {
+            LazyLookupProviders.LOG.log(Level.WARNING, null, new IllegalStateException("may not call Project.getLookup().lookup(...) inside " + member.getName() + " registered under @ProjectServiceProvider"));
+        }
+    }
+    
+    static Object loadPSPInstance(String implName, String methodName, Lookup lkp) throws Exception {
         ClassLoader loader = Lookup.getDefault().lookup(ClassLoader.class);
         if (loader == null) {
             loader = Thread.currentThread().getContextClassLoader();
diff --git a/ide/projectapi/src/org/netbeans/spi/project/support/DelegatingLookupImpl.java b/ide/projectapi/src/org/netbeans/spi/project/support/DelegatingLookupImpl.java
index c41a343..c3eb60c 100644
--- a/ide/projectapi/src/org/netbeans/spi/project/support/DelegatingLookupImpl.java
+++ b/ide/projectapi/src/org/netbeans/spi/project/support/DelegatingLookupImpl.java
@@ -27,6 +27,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.Executor;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import javax.swing.event.ChangeEvent;
@@ -47,7 +48,8 @@
 
     private final Lookup baseLookup;
     private final String pathDescriptor;
-    private final UnmergedLookup unmergedLookup = new UnmergedLookup();
+    private final Controller unmergedController;
+    private final ProxyLookup unmergedLookup;
     private final Map<LookupMerger<?>,Object> mergerResults = new HashMap<LookupMerger<?>,Object>();
     private final Lookup.Result<LookupProvider> providerResult;
     private final LookupListener providerListener;
@@ -63,6 +65,8 @@
     @SuppressWarnings("LeakingThisInConstructor")
     DelegatingLookupImpl(Lookup base, Lookup providerLookup, String pathDescriptor) {
         assert base != null;
+        this.unmergedController = new ProxyLookup.Controller();
+        this.unmergedLookup = new ProxyLookup(this.unmergedController);
         baseLookup = base;
         this.pathDescriptor = pathDescriptor;
         providerResult = providerLookup.lookupResult(LookupProvider.class);
@@ -96,6 +100,24 @@
     }
 
     private void doDelegate() {
+        class NotifyLater implements Executor {
+            List<Runnable> pending = new ArrayList<>();
+
+            @Override
+            public void execute(Runnable command) {
+                pending.add(command);
+            }
+
+            public void notifyCollectedEvents() {
+                List<Runnable> tmp = pending;
+                pending = null;
+                for (Runnable r : tmp) {
+                    r.run();
+                }
+            }
+        }
+        NotifyLater notifyLater = new NotifyLater();
+
         synchronized (results) {
             for (Lookup.Result<?> r : results) {
                 r.removeLookupListener(this);
@@ -125,7 +147,7 @@
             old = new ArrayList<LookupProvider>(providers);
             currentLookups = newLookups;
             newLookups.add(baseLookup);
-            unmergedLookup._setLookups(newLookups.toArray(new Lookup[newLookups.size()]));
+            unmergedController.setLookups(notifyLater, newLookups.toArray(new Lookup[newLookups.size()]));
             List<Class<?>> filteredClasses = new ArrayList<Class<?>>();
             List<Object> mergedInstances = new ArrayList<Object>();
             LookupListener l = listenerRef != null ? listenerRef.get() : null;
@@ -165,14 +187,13 @@
             }
             Lookup filtered = Lookups.exclude(unmergedLookup, filteredClasses.toArray(new Class<?>[filteredClasses.size()]));
             Lookup fixed = Lookups.fixed(mergedInstances.toArray(new Object[mergedInstances.size()]));
-            setLookups(fixed, filtered);
+            setLookups(notifyLater, fixed, filtered);
         }
+        notifyLater.notifyCollectedEvents();
     }
 
-    private static class UnmergedLookup extends ProxyLookup {
-        void _setLookups(Lookup... lookups) {
-            setLookups(lookups);
-        }
+    final boolean holdsLock() {
+        return Thread.holdsLock(results);
     }
 
     //just for assertion evaluation.
diff --git a/ide/projectapi/test/unit/src/org/netbeans/modules/projectapi/LazyLookupTest.java b/ide/projectapi/test/unit/src/org/netbeans/modules/projectapi/LazyLookupTest.java
new file mode 100644
index 0000000..3a99cb4
--- /dev/null
+++ b/ide/projectapi/test/unit/src/org/netbeans/modules/projectapi/LazyLookupTest.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.projectapi;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.Test;
+import static org.junit.Assert.*;
+import org.openide.util.Lookup;
+import org.openide.util.LookupEvent;
+import org.openide.util.LookupListener;
+
+public class LazyLookupTest {
+    
+    public LazyLookupTest() {
+    }
+    
+    @Test
+    public void testChangesAreNotifiedWithoutHoldingALock() {
+        
+        Map<String,Object> data = new HashMap<>();
+        data.put("service", String.class.getName());
+        data.put("class", LazyLookupTest.class.getName());
+        data.put("method", "testFactory");
+        LazyLookup lkp = new LazyLookup(data, Lookup.EMPTY);
+
+        class LL implements LookupListener {
+            int cnt;
+            
+            @Override
+            public void resultChanged(LookupEvent ev) {
+                cnt++;
+                assertFalse("Internal lock isn't held", lkp.isInitializing());
+            }
+        }
+        LL listener = new LL();
+
+        Lookup.Result<String> res = lkp.lookupResult(String.class);
+        res.addLookupListener(listener);
+        
+        String value = lkp.lookup(String.class);
+        assertEquals("Hello", value);
+        
+        assertEquals("One change", 1, listener.cnt);
+    }
+    
+    public static String testFactory() {
+        return "Hello";
+    }
+}
diff --git a/ide/projectapi/test/unit/src/org/netbeans/spi/project/support/DelegatingLookupDeadlock5914Test.java b/ide/projectapi/test/unit/src/org/netbeans/spi/project/support/DelegatingLookupDeadlock5914Test.java
new file mode 100644
index 0000000..453d9ca
--- /dev/null
+++ b/ide/projectapi/test/unit/src/org/netbeans/spi/project/support/DelegatingLookupDeadlock5914Test.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.netbeans.spi.project.support;
+
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JRadioButton;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import org.netbeans.junit.NbTestCase;
+import org.netbeans.spi.project.LookupMerger;
+import org.netbeans.spi.project.LookupProvider;
+import org.openide.util.Lookup;
+import org.openide.util.LookupEvent;
+import org.openide.util.LookupListener;
+import org.openide.util.lookup.AbstractLookup;
+import org.openide.util.lookup.InstanceContent;
+import org.openide.util.lookup.Lookups;
+
+public class DelegatingLookupDeadlock5914Test extends NbTestCase {
+
+    public DelegatingLookupDeadlock5914Test(String name) {
+        super(name);
+    }
+
+    public void testDontHoldLockWhenNotifyingChanges() {
+        LookupMergerImpl merger = new LookupMergerImpl();
+        Lookup base = Lookups.fixed(new JButton(), new JComboBox(), merger);
+        LookupProviderImpl pro1 = new LookupProviderImpl();
+        LookupProviderImpl pro2 = new LookupProviderImpl();
+        LookupProviderImpl pro3 = new LookupProviderImpl();
+
+        InstanceContent provInst = new InstanceContent();
+        Lookup providers = new AbstractLookup(provInst);
+        provInst.add(pro1);
+        provInst.add(pro2);
+
+        pro1.ic.add(new JTextField());
+        pro2.ic.add(new JTextArea());
+
+        DelegatingLookupImpl del = new DelegatingLookupImpl(base, providers, "<irrelevant>");
+        class LL implements LookupListener {
+            int cnt;
+
+            @Override
+            public void resultChanged(LookupEvent ev) {
+                assertFalse("Cannot hold lock when notifying changes!", del.holdsLock());
+                cnt++;
+            }
+        }
+        LL jbuttonListener = new LL();
+        Lookup.Result<JButton> jbuttonResult = del.lookupResult(JButton.class);
+        jbuttonResult.addLookupListener(jbuttonListener);
+        assertEquals("One button", 1, jbuttonResult.allInstances().size());
+
+        Lookup.Result<JRadioButton> jradioButtonResult = del.lookupResult(JRadioButton.class);
+        LL jradioButtonListener = new LL();
+        jradioButtonResult.addLookupListener(jradioButtonListener);
+        assertEquals("No radio button", 0, jradioButtonResult.allInstances().size());
+
+        assertNotNull(del.lookup(JTextArea.class));
+        assertNotNull(del.lookup(JComboBox.class));
+
+        // test merger..
+        JButton butt = del.lookup(JButton.class);
+        assertNotNull(butt);
+        assertEquals("CORRECT", butt.getText());
+        assertEquals(1, del.lookupAll(JButton.class).size());
+        assertEquals(1, merger.expectedCount);
+
+        pro3.ic.add(new JButton());
+        pro3.ic.add(new JRadioButton());
+        provInst.add(pro3);
+        assertNotNull(del.lookup(JRadioButton.class));
+
+        assertEquals("A change delivered", 1, jradioButtonListener.cnt);
+    }
+
+    private static class LookupMergerImpl implements LookupMerger<JButton> {
+
+        int expectedCount;
+
+        @Override public Class<JButton> getMergeableClass() {
+            return JButton.class;
+        }
+
+        @Override public JButton merge(final Lookup lookup) {
+            expectedCount = lookup.lookupAll(JButton.class).size();
+            lookup.lookupResult(JButton.class).addLookupListener(new LookupListener() {
+                public @Override void resultChanged(LookupEvent ev) {
+                    expectedCount = lookup.lookupAll(JButton.class).size();
+                }
+            });
+            return new JButton("CORRECT");
+        }
+
+    }
+
+    private static class LookupProviderImpl implements LookupProvider {
+        InstanceContent ic = new InstanceContent();
+        boolean wasAlreadyCalled = false;
+        @Override public Lookup createAdditionalLookup(Lookup baseContext) {
+            assertNotNull(baseContext.lookup(JButton.class));
+            assertNull(baseContext.lookup(JCheckBox.class));
+            assertFalse(wasAlreadyCalled);
+            wasAlreadyCalled = true;
+            return new AbstractLookup(ic);
+        }
+    }
+
+}
diff --git a/nb/ide.launcher/netbeans.conf b/nb/ide.launcher/netbeans.conf
index edc8226..c12595e 100644
--- a/nb/ide.launcher/netbeans.conf
+++ b/nb/ide.launcher/netbeans.conf
@@ -63,7 +63,7 @@
 # (see: https://issues.apache.org/jira/browse/NETBEANS-1344)
 #
 
-netbeans_default_options="-J-XX:+UseStringDeduplication -J-Xss2m @@metabuild.logcli@@ -J-Dapple.laf.useScreenMenuBar=true -J-Dapple.awt.graphics.UseQuartz=true -J-Dsun.java2d.noddraw=true -J-Dsun.java2d.dpiaware=true -J-Dsun.zip.disableMemoryMapping=true -J-Dplugin.manager.check.updates=false -J-Dnetbeans.extbrowser.manual_chrome_plugin_install=yes -J--add-opens=java.base/java.net=ALL-UNNAMED -J--add-opens=java.base/java.lang.ref=ALL-UNNAMED -J--add-opens=java.base/java.lang=ALL-UNNAMED -J--add-opens=java.base/java.security=ALL-UNNAMED -J--add-opens=java.base/java.util=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing.plaf.basic=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing.text=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing=ALL-UNNAMED -J--add-opens=java.desktop/java.awt=ALL-UNNAMED -J--add-opens=java.desktop/java.awt.event=ALL-UNNAMED -J--add-opens=java.prefs/java.util.prefs=ALL-UNNAMED -J--add-opens=jdk.jshell/jdk.jshell=ALL-UNNAMED -J--add-modules=jdk.jshell -J--add-exports=java.desktop/sun.awt=ALL-UNNAMED -J--add-exports=java.desktop/java.awt.peer=ALL-UNNAMED -J--add-exports=java.desktop/com.sun.beans.editors=ALL-UNNAMED -J--add-exports=java.desktop/sun.swing=ALL-UNNAMED -J--add-exports=java.desktop/sun.awt.im=ALL-UNNAMED -J--add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED -J--add-exports=java.management/sun.management=ALL-UNNAMED -J--add-exports=java.base/sun.reflect.annotation=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED  -J--add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED -J--add-exports=jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED -J--add-exports=jdk.jdeps/com.sun.tools.javap=ALL-UNNAMED -J--add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED -J-XX:+IgnoreUnrecognizedVMOptions"
+netbeans_default_options="-J-XX:+UseStringDeduplication -J-Xss2m @@metabuild.logcli@@ -J-Dapple.laf.useScreenMenuBar=true -J-Dapple.awt.graphics.UseQuartz=true -J-Dsun.java2d.noddraw=true -J-Dsun.java2d.dpiaware=true -J-Dsun.zip.disableMemoryMapping=true -J-Dplugin.manager.check.updates=false -J-Dnetbeans.extbrowser.manual_chrome_plugin_install=yes -J--add-opens=java.base/java.net=ALL-UNNAMED -J--add-opens=java.base/java.lang.ref=ALL-UNNAMED -J--add-opens=java.base/java.lang=ALL-UNNAMED -J--add-opens=java.base/java.security=ALL-UNNAMED -J--add-opens=java.base/java.util=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing.plaf.basic=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing.text=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing=ALL-UNNAMED -J--add-opens=java.desktop/java.awt=ALL-UNNAMED -J--add-opens=java.desktop/java.awt.event=ALL-UNNAMED -J--add-opens=java.prefs/java.util.prefs=ALL-UNNAMED -J--add-opens=jdk.jshell/jdk.jshell=ALL-UNNAMED -J--add-modules=jdk.jshell -J--add-exports=java.desktop/sun.awt=ALL-UNNAMED -J--add-exports=java.desktop/java.awt.peer=ALL-UNNAMED -J--add-exports=java.desktop/com.sun.beans.editors=ALL-UNNAMED -J--add-exports=java.desktop/sun.swing=ALL-UNNAMED -J--add-exports=java.desktop/sun.awt.im=ALL-UNNAMED -J--add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED -J--add-exports=java.management/sun.management=ALL-UNNAMED -J--add-exports=java.base/sun.reflect.annotation=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED  -J--add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED -J--add-exports=jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED -J--add-exports=jdk.jdeps/com.sun.tools.javap=ALL-UNNAMED -J--add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing.plaf.synth=ALL-UNNAMED -J--add-opens=java.desktop/com.sun.java.swing.plaf.gtk=ALL-UNNAMED -J--add-opens=java.desktop/sun.awt.shell=ALL-UNNAMED -J--add-opens=java.desktop/sun.awt.im=ALL-UNNAMED -J--add-opens=java.base/java.nio=ALL-UNNAMED  -J-XX:+IgnoreUnrecognizedVMOptions"
 
 # Default location of JDK:
 # (set by installer or commented out if launcher should decide)