If you find the File -> Open dialog very slow in SQL Developer 22.2 on Windows, and you just can't wait, here's how to fix it yourself... if you're ready to build the JDK from the sources, that is. It's not a very difficult thing to do, provided you're familiar enough with the required tools.
For a reminder about why the File -> Open (or Save As) dialog can be so slow in SQL Developer 22.2 on Windows, please see this thread. This issue may also affect the IndexPreferences task.
Here I will share a tiny patch for the JDK, to be applied to the sources of the OpenJDK project, along with a summary of how I did the build, and used it along with SQL Developer 22.2.1.
Important: you should be familiar with installation and use of the Cygwin environment (it is required for building the JDK on Windows), and with build procedures in general.
1/ Links
OpenJDK sources, as of release 11.0.16.1-ga: https://github.com/openjdk/jdk11u-dev/releases/tag/jdk-11.0.16.1-ga
Build instructions for the same: https://github.com/openjdk/jdk11u-dev/blob/master/doc/building.md
Binaries of the OpenJDK release jdk-11.0.16.1+1, to be used as the bootstrap JDK: https://adoptium.net/temurin/archive/?version=11 (or direct link: https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.16.1%2B1/OpenJDK11U-jdk_x64_windows_hotspot_11.0.16.1_1.zip)
Microsoft pre-built VMs for Windows 11 development (evaluation license): https://developer.microsoft.com/en-us/windows/downloads/virtual-machines/
Home of the Cygwin project: http://www.cygwin.com/
VirtualBox download page: https://www.virtualbox.org/wiki/Downloads
2/ Requirements
2.a/ Hardware requirements
A powerful enough PC is needed, with plenty of RAM, plus disk space on a fast SSD drive: on top of the requirements for building the JDK (2-4 CPU cores advisable, 2-4 Gb of RAM, 6 Gb of free disk space), you may have to add a lot more if you'll be using a virtual machine for setting up the build environment: say 16 Gb of RAM (of which 8 Gb for the virtual machine), and 150 Gb of free disk space on your SSD drive.
2.b/ Software requirements
When building for the Windows target platform, the software requirements include:
Cygwin (preferably in a fresh enough release)
Microsoft Visual Studio, 2019 or higher
I don't have Microsoft Visual Studio 2019, and my Windows 7 PC is now out of support, and too old for installing it anyway... Fortunately, a quick and easy solution is available: Microsoft provides pre-built evaluation VMs of Windows 11, with Visual Studio 2022 (Community Edition) pre-installed, and that's all we need. 🙂 So I just upgraded VirtualBox, to the latest 6.1.40 release, downloaded the pre-built VM gently provided by Microsoft, and fired it up. It turned out to be perfect for the job.
2.c/ Bootstrap JDK
It takes one to build one: you need a working JDK to build a newer one from its sources, and in principle that "bootstrap" JDK should be of the previous major release. What is release N-1 for Java 11? I don't know; meanwhile, the build instructions mention that the JDK should be able to "build itself", so that's what I used here.
3/ The Patch
The patch reads as follows (including the final blank line):
diff --git a/src/java.base/windows/classes/java/io/WinNTFileSystem.java b/src/java.base/windows/classes/java/io/WinNTFileSystem.java
index efe64b1a57..6b91cd7b0f 100644
--- a/src/java.base/windows/classes/java/io/WinNTFileSystem.java
+++ b/src/java.base/windows/classes/java/io/WinNTFileSystem.java
@@ -60,6 +60,21 @@ class WinNTFileSystem extends FileSystem {
}
}
+ // Whether listRoots() will skip invoking File.exists() on each available
+ // filesystem root or not. By default, each available root is checked, and
+ // this check is bypassed if and only if the property is set, ignoring
+ // case, to the string "true".
+ private static final boolean UNCHECKED_LISTROOTS;
+ static {
+ String uncheckedListRoots = GetPropertyAction.privilegedGetProperty(
+ "java.io.WinNTFileSystem.uncheckedListRoots");
+ if (uncheckedListRoots != null) {
+ UNCHECKED_LISTROOTS = uncheckedListRoots.equalsIgnoreCase(Boolean.TRUE.toString());
+ } else {
+ UNCHECKED_LISTROOTS = false;
+ }
+ }
+
public WinNTFileSystem() {
Properties props = GetPropertyAction.privilegedGetProperties();
slash = props.getProperty("file.separator").charAt(0);
@@ -642,7 +657,9 @@ class WinNTFileSystem extends FileSystem {
.valueOf(new long[] {listRoots0()})
.stream()
.mapToObj(i -> new File((char)('A' + i) + ":" + slash))
- .filter(f -> access(f.getPath()) && f.exists())
+ .filter((UNCHECKED_LISTROOTS
+ ? f -> access(f.getPath())
+ : f -> access(f.getPath()) && f.exists()))
.toArray(File[]::new);
}
I include the patch file here (compressed with gzip) in order to spare error-prone file manipulations.
WinNTFileSystem.java.diff.gz (735 Bytes)In simple words, what this does is:
a) At class-initialization time, find out whether the java.io.WinNTFileSystem.uncheckedListRoots
JVM property is set and equal to true.
b) If (and only if) it is, subsequently calls to File.exists()
which, in the listRoots()
method, check whether each filesystem root actually exists, will be disabled, thereby reverting listRoots()
to its pre-Java 11 behaviour—known to be incorrect, but much faster, and (hopefully) good enough for SQL Developer 22.2.
4/ Software setup
4.a/ Windows 11 guest host
The Windows 11 evaluation pre-built VM comes with Microsoft Visual Studio 2022 (Community Edition) pre-installed, hence not much else is needed aside of Cygwin. I installed Firefox, gvim, Git, KDiff3, and other software in order to feel more at home, but actually none of these is stricly necessary.
4.b/ Cygwin
According to the build instructions, the mandatory Cygwin packages for building the JDK are as follows:
autoconf
make
zip
unzip
To the above I added the following:
diffutils
p7zip
patch
4.c/ Bootstrap JDK
I downloaded the binaries of the Open JDK from adoptium.net, in release jdk-11.0.16.1+1 (see Links above), using the ZIP archive (aka non-installer), and I deflated it in such a way that the actual path to the java.exe
binary is C:\Products\Java\OpenJDK\jdk-11.0.16.1+1\bin\java.exe
5/ Download the sources
Because SQL Developer 22.2.1 comes bundled with the Oracle JDK in release 11.0.16.1, we'll use the closest corresponding release from the OpenJDK project, namely 11.0.16.1-ga. See Links above.
6/ Build step
6.a/ Working directory
My top-level work directory is C:\Projects\src
The JDK sources will be deflated into C:\Projects\src\jdk11u-dev-jdk-11.0.16.1-ga
Everything will be built in subdirectories of that directory.
6.b/ Expand the JDK sources
cd /cygdrive/C/Projects/src
For convenience, I used 7zip for extracting from the zip package
7z x jdk11u-dev-jdk-11.0.16.1-ga.zip
6.c/ CD into the top directory of the source tree
cd jdk11u-dev-jdk-11.0.16.1-ga
6.d/ Apply the patch
patch --verbose -p1 < /cygdrive/C/path_to/WinNTFileSystem.java.diff
Hmm... Looks like a unified diff to me...
The text leading up to this was:
--------------------------
|diff --git a/src/java.base/windows/classes/java/io/WinNTFileSystem.java b/src/java.base/windows/classes/java/io/WinNTFileSystem.java
|index efe64b1a57..6b91cd7b0f 100644
|--- a/src/java.base/windows/classes/java/io/WinNTFileSystem.java
|+++ b/src/java.base/windows/classes/java/io/WinNTFileSystem.java
--------------------------
patching file src/java.base/windows/classes/java/io/WinNTFileSystem.java
Using Plan A...
Hunk #1 succeeded at 60.
Hunk #2 succeeded at 657.
done
6.e/ Run configure
$ bash ./configure \
--with-boot-jdk=/cygdrive/C/Products/Java/OpenJDK/jdk-11.0.16.1+1 \
--with-tools-dir="/cygdrive/C/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE"
6.f/ Run make
make
make product-images
On my old PC (quad-core i7-860 from 2009 + SATA SSD), the build times were 39 mins for make
, then 7 mins for make product-images
.
(With virus-scanning temporarily disabled, as it appeared to eat a lot of CPU-time, possibly slowing things down.)
6.g/ Check the results
Everything is built in the build/windows-x86_64-normal-server-release
subdirectory. Log files are available in that directory as configure.log
, build.log
, build.log.old
.
The final JDK image is found in the images/jdk
subdirectory of that directory.
cd build/windows-x86_64-normal-server-release/images/jdk
./bin/java -version
openjdk version "11.0.16.1-internal" 2022-08-12
OpenJDK Runtime Environment (build 11.0.16.1-internal+0-adhoc.User.jdk11u-dev-jdk-11.0.16.1-ga)
OpenJDK 64-Bit Server VM (build 11.0.16.1-internal+0-adhoc.User.jdk11u-dev-jdk-11.0.16.1-ga, mixed mode)
It seems to work!
6.h/ Zip the new JDK image
zip -r jdku11.0.16.1-ga+.zip .
At this stage, the new JDK, packed as a ZIP archive, is ready to be moved from the guest host to the target host.
The name of the archive (jdku11.0.16.1-ga+.zip
) ends with a "+" character, as a small reminder that this is the GA release plus one patch—of course this is a strictly "home-only" build, not meant to be redistributed.
7/ Using it in SQL Developer 22.2.1
7.a/ Expand the new JDK from its zip archive into its installation folder
In my case, I installed the new JDK into the following location:
F:\Produits\Win_7\Java\OpenJDK\jdku11.0.16.1-ga+
So that the new java.exe
binary is F:\Produits\Win_7\Java\OpenJDK\jdku11.0.16.1-ga+\bin\java.exe
7.b/ Update product.conf
The following line must be added to product.conf
, in the %APPDATA%\sqldeveloper\22.2.1
directory:
SetJavaHome F:\Produits\Win_7\Java\OpenJDK\jdku11.0.16.1-ga+
7.c/ Update sqldeveloper.conf
The sqldeveloper.conf
file, in the sqldeveloper\bin
subdirectory under the top-level installation directory of SQL Developer 22.2.1, must be changed by adding the following 2 lines:
#Enable unchecked File.listRoots()
AddVMOption -Djava.io.WinNTFileSystem.uncheckedListRoots=true
7.d/ Start SQL Developer
Then you may use the Help -> About dialog, Properties tab, and check the following JVM properties:
java.home F:\Produits\Win_7\Java\OpenJDK\jdku11.0.16.1-ga+
java.version 11.0.16.1-internal
java.vm.version 11.0.16.1-internal+0-adhoc.User.jdk11u-dev-jdk-11.0.16.1-ga
java.runtime.version 11.0.16.1-internal+0-adhoc.User.jdk11u-dev-jdk-11.0.16.1-ga
And, of course, our special JVM property for making File.listRoots()
fast again:
java.io.WinNTFileSystem.uncheckedListRoots true
Then try File -> Open, see if it makes a difference for you.
If that works, fine!
Just remember that this lands you in a totally unsupported territory: only Oracle JDKs are officially supported with SQL Developer, which means that, should you encounter a bug, Oracle may ask you to reproduce it using a supported Oracle JDK. In principle, the JDK from the OpenJDK project and the corresponding Oracle JDK at the same release level are distinct, in that the Oracle JDK may have an unspecified number of additional fixes on top of the OpenJDK sources—the exact list is not publicly available, but we may expect it to be small; AFAIU, the idea is that Oracle may push specific fixes that its clients need, but which are not (or not yet) included in the main OpenJDK sources.
Hope this helps...
Regards,