diff --git a/ide/db/src/org/netbeans/modules/db/explorer/dlg/AddDriverDialog.java b/ide/db/src/org/netbeans/modules/db/explorer/dlg/AddDriverDialog.java index ac0b36b2790a..3a2042bf2780 100644 --- a/ide/db/src/org/netbeans/modules/db/explorer/dlg/AddDriverDialog.java +++ b/ide/db/src/org/netbeans/modules/db/explorer/dlg/AddDriverDialog.java @@ -570,30 +570,25 @@ public void run() { URLClassLoader jarloader = getJarClassLoader(); for (int i = 0; i < dlm.size(); i++) { - try { - String file = dlm.get(i); - JarFile jf = new JarFile(file); - try { - Enumeration entries = jf.entries(); - while (entries.hasMoreElements()) { - JarEntry entry = (JarEntry)entries.nextElement(); - String className = entry.getName(); - if (className.endsWith(".class")) { // NOI18N - className = className.replace('/', '.'); - className = className.substring(0, className.length() - 6); - if ( isDriverClass(jarloader, className) ) { - if (progressHandle != null) { - addDriverClass(className); - } else { - // already stopped - updateState(); - return; - } + String file = dlm.get(i); + try (JarFile jf = new JarFile(file)) { + Enumeration entries = jf.entries(); + while (entries.hasMoreElements()) { + JarEntry entry = (JarEntry) entries.nextElement(); + String className = entry.getName(); + if (className.endsWith(".class")) { // NOI18N + className = className.replace('/', '.'); + className = className.substring(0, className.length() - 6); + if (isDriverClass(jarloader, className)) { + if (progressHandle != null) { + addDriverClass(className); + } else { + // already stopped + updateState(); + return; } } } - } finally { - jf.close(); } } catch (IOException exc) { //PENDING diff --git a/ide/db/src/org/netbeans/modules/db/util/Bundle.properties b/ide/db/src/org/netbeans/modules/db/util/Bundle.properties index 84bde29ab8ee..bcb031bc9dcc 100644 --- a/ide/db/src/org/netbeans/modules/db/util/Bundle.properties +++ b/ide/db/src/org/netbeans/modules/db/util/Bundle.properties @@ -33,8 +33,10 @@ ERR_InvalidURL=Invalid URL, should be of the form \n{0} DRIVERNAME_MySQL=MySQL (Connector/J driver) DRIVERNAME_MariaDB=MariaDB (MySQL-compatible) -DRIVERNAME_JavaDbEmbedded=Java DB (Embedded) -DRIVERNAME_JavaDbNetwork=Java DB (Network) +DRIVERNAME_JavaDbEmbedded=Java DB (Embedded, version <= 10.14) +DRIVERNAME_JavaDbNetwork=Java DB (Network, version <= 10.14) +DRIVERNAME_JavaDbEmbeddedModular=Java DB (Embedded, version >= 10.15) +DRIVERNAME_JavaDbNetworkModular=Java DB (Network, version >= 10.15) DRIVERNAME_PostgreSQL=PostgreSQL DRIVERNAME_OracleThin=Oracle Thin DRIVERNAME_OracleOCI=Oracle OCI diff --git a/ide/db/src/org/netbeans/modules/db/util/DriverListUtil.java b/ide/db/src/org/netbeans/modules/db/util/DriverListUtil.java index 2831cb57274d..12813638cd13 100644 --- a/ide/db/src/org/netbeans/modules/db/util/DriverListUtil.java +++ b/ide/db/src/org/netbeans/modules/db/util/DriverListUtil.java @@ -96,11 +96,19 @@ private static JdbcUrl add(String name, String driverClassName, String urlTempla add("Cloudscape RMI", "RmiJdbc.RJDriver", "jdbc:rmi://[:]/jdbc:cloudscape:"); + + add(NbBundle.getMessage(DriverListUtil.class, "DRIVERNAME_JavaDbEmbeddedModular"), + "org.apache.derby.iapi.jdbc.AutoloadedDriver", + "jdbc:derby:[;]", true); + + add(NbBundle.getMessage(DriverListUtil.class, "DRIVERNAME_JavaDbNetworkModular"), + "org.apache.derby.client.ClientAutoloadedDriver", + "jdbc:derby://[:]/[;]", true); add(NbBundle.getMessage(DriverListUtil.class, "DRIVERNAME_JavaDbEmbedded"), "org.apache.derby.jdbc.EmbeddedDriver", "jdbc:derby:[;]", true); - + add(NbBundle.getMessage(DriverListUtil.class, "DRIVERNAME_JavaDbNetwork"), "org.apache.derby.jdbc.ClientDriver", "jdbc:derby://[:]/[;]", true); diff --git a/ide/derby/src/org/netbeans/modules/derby/ConnectDatabaseAction.java b/ide/derby/src/org/netbeans/modules/derby/ConnectDatabaseAction.java index fb8bbfa5d160..aac1b686f410 100644 --- a/ide/derby/src/org/netbeans/modules/derby/ConnectDatabaseAction.java +++ b/ide/derby/src/org/netbeans/modules/derby/ConnectDatabaseAction.java @@ -19,6 +19,7 @@ package org.netbeans.modules.derby; +import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -35,6 +36,8 @@ import org.openide.util.NbBundle; import org.openide.util.actions.NodeAction; +import static java.util.Arrays.asList; + /** * Connect to a database * @@ -77,12 +80,14 @@ protected void performAction(Node[] activatedNodes) { try { if ( conns.isEmpty() ) { - JDBCDriver drivers[] = JDBCDriverManager.getDefault().getDrivers(DerbyOptions.DRIVER_CLASS_NET); - if (drivers.length == 0) { + List drivers = new ArrayList<>(); + drivers.addAll(asList(JDBCDriverManager.getDefault().getDrivers(DerbyOptions.DRIVER_CLASS_NET))); + drivers.addAll(asList(JDBCDriverManager.getDefault().getDrivers(DerbyOptions.DRIVER_CLASS_NET_MODULAR))); + if (drivers.isEmpty()) { showDriverNotFoundDialog(); return; } - final DatabaseConnection dbconn = DatabaseConnection.create(drivers[0], "jdbc:derby://localhost:" + // NOI18N + final DatabaseConnection dbconn = DatabaseConnection.create(drivers.get(0), "jdbc:derby://localhost:" + // NOI18N RegisterDerby.getDefault().getPort() + "/" + dbname, // NOI18N DerbyDatabasesImpl.getDefault().getUser(dbname), diff --git a/ide/derby/src/org/netbeans/modules/derby/DerbyDatabasesImpl.java b/ide/derby/src/org/netbeans/modules/derby/DerbyDatabasesImpl.java index a06ccf96f7e5..c607a48e024c 100644 --- a/ide/derby/src/org/netbeans/modules/derby/DerbyDatabasesImpl.java +++ b/ide/derby/src/org/netbeans/modules/derby/DerbyDatabasesImpl.java @@ -52,6 +52,8 @@ import org.openide.util.Exceptions; import org.openide.util.NbPreferences; +import static java.util.Arrays.asList; + /** * * @author Andrei Badea, Jiri Rechtacek @@ -488,15 +490,17 @@ private File ensureSystemHome() throws IOException { * on the local Derby server. */ private synchronized DatabaseConnection registerDatabase(String databaseName, String user, String schema, String password, boolean rememberPassword) throws DatabaseException { - JDBCDriver drivers[] = JDBCDriverManager.getDefault().getDrivers(DerbyOptions.DRIVER_CLASS_NET); - if (drivers.length == 0) { + List drivers = new ArrayList<>(); + drivers.addAll(asList(JDBCDriverManager.getDefault().getDrivers(DerbyOptions.DRIVER_CLASS_NET))); + drivers.addAll(asList(JDBCDriverManager.getDefault().getDrivers(DerbyOptions.DRIVER_CLASS_NET_MODULAR))); + if (drivers.isEmpty()) { throw new IllegalStateException("The " + DerbyOptions.DRIVER_DISP_NAME_NET + " driver was not found"); // NOI18N } Preferences pref = NbPreferences.root().node(PATH_TO_DATABASE_PREFERENCES + databaseName); pref.put(USER_KEY, user == null ? "" : user); pref.put(SCHEMA_KEY, schema == null ? "" : schema); pref.put(PASSWORD_KEY, password == null ? "" : password); - DatabaseConnection dbconn = DatabaseConnection.create(drivers[0], "jdbc:derby://localhost:" + RegisterDerby.getDefault().getPort() + "/" + databaseName, user, schema, password, rememberPassword); // NOI18N + DatabaseConnection dbconn = DatabaseConnection.create(drivers.get(0), "jdbc:derby://localhost:" + RegisterDerby.getDefault().getPort() + "/" + databaseName, user, schema, password, rememberPassword); // NOI18N if (ConnectionManager.getDefault().getConnection(dbconn.getName()) == null) { ConnectionManager.getDefault().addConnection(dbconn); } @@ -551,8 +555,19 @@ private Driver loadDerbyNetDriver() throws DatabaseException, IllegalStateExcep } URL[] driverURLs = new URL[] { derbyClient.toURI().toURL() }; // NOI18N DbURLClassLoader l = new DbURLClassLoader(driverURLs); - Class c = Class.forName(DerbyOptions.DRIVER_CLASS_NET, true, l); - return (Driver)c.getDeclaredConstructor().newInstance(); + Class driverClass = null; + for (String driverCandidate : new String[]{DerbyOptions.DRIVER_CLASS_NET, DerbyOptions.DRIVER_CLASS_NET_MODULAR}) { + try { + driverClass = Class.forName(driverCandidate, true, l); + break; + } catch (ClassNotFoundException ex) { + exception = ex; + } + } + if(driverClass != null) { + exception = null; + } + return (Driver)driverClass.getDeclaredConstructor().newInstance(); } catch (MalformedURLException | ReflectiveOperationException e) { exception = e; } @@ -581,13 +596,14 @@ void notifyChange() { List findDatabaseConnections(String databaseName) { String url = "jdbc:derby://localhost:" + RegisterDerby.getDefault().getPort() + "/" + databaseName; - List result = new ArrayList(); + List result = new ArrayList<>(); DatabaseConnection[] connections = ConnectionManager.getDefault().getConnections(); for (DatabaseConnection conn : connections) { // If there's already a connection registered, we're done - if (conn.getDriverClass().equals(DerbyOptions.DRIVER_CLASS_NET) + if ((conn.getDriverClass().equals(DerbyOptions.DRIVER_CLASS_NET) + || conn.getDriverClass().equals(DerbyOptions.DRIVER_CLASS_NET_MODULAR)) && conn.getDatabaseURL().equals(url)) { result.add(conn); } diff --git a/ide/derby/src/org/netbeans/modules/derby/DerbyOptions.java b/ide/derby/src/org/netbeans/modules/derby/DerbyOptions.java index 5db2bfe83d75..114e7cad44f2 100644 --- a/ide/derby/src/org/netbeans/modules/derby/DerbyOptions.java +++ b/ide/derby/src/org/netbeans/modules/derby/DerbyOptions.java @@ -27,6 +27,7 @@ import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; +import java.util.jar.JarFile; import java.util.logging.Level; import java.util.logging.Logger; import org.netbeans.api.db.explorer.DatabaseException; @@ -67,7 +68,9 @@ public class DerbyOptions { static final String INST_DIR = "db-derby-10.14.2.0"; // NOI18N public static final String DRIVER_CLASS_NET = "org.apache.derby.jdbc.ClientDriver"; // NOI18N + public static final String DRIVER_CLASS_NET_MODULAR = "org.apache.derby.client.ClientAutoloadedDriver"; // NOI18N public static final String DRIVER_CLASS_EMBEDDED = "org.apache.derby.jdbc.EmbeddedDriver"; // NOI18N + public static final String DRIVER_CLASS_EMBEDDED_MODULAR = "org.apache.derby.iapi.jdbc.AutoloadedDriver"; // NOI18N private static final String DRIVER_PATH_NET = "lib/derbyclient.jar"; // NOI18N private static final String DRIVER_PATH_EMBEDDED = "lib/derby.jar"; // NOI18N @@ -252,8 +255,12 @@ private static void registerDrivers(final String newLocation) { public void run() { registerDriver(DRIVER_NAME_NET, DRIVER_DISP_NAME_NET, DRIVER_CLASS_NET, new String[]{DRIVER_PATH_NET, DRIVER_PATH_EMBEDDED}, newLocation); + registerDriver(DRIVER_NAME_NET, DRIVER_DISP_NAME_NET, DRIVER_CLASS_NET_MODULAR, + new String[]{DRIVER_PATH_NET, DRIVER_PATH_EMBEDDED}, newLocation); registerDriver(DRIVER_NAME_EMBEDDED, DRIVER_DISP_NAME_EMBEDDED, DRIVER_CLASS_EMBEDDED, new String[]{DRIVER_PATH_EMBEDDED}, newLocation); + registerDriver(DRIVER_NAME_EMBEDDED, DRIVER_DISP_NAME_EMBEDDED, + DRIVER_CLASS_EMBEDDED_MODULAR, new String[]{DRIVER_PATH_EMBEDDED}, newLocation); } }); } catch (IOException e) { @@ -315,15 +322,19 @@ private static void registerDriver(String driverName, String driverDisplayName, if (newLocation != null && newLocation.length() >= 0) { URL[] driverFileUrls = new URL[driverRelativeFile.length]; try { + boolean driverClassFound = false; for (int i = 0; i < driverRelativeFile.length; i++) { File drvFile = new File(newLocation, driverRelativeFile[i]); + driverClassFound |= containsClass(drvFile, driverClass); if (!drvFile.exists()) { return; } driverFileUrls[i] = drvFile.toURI().toURL(); } - JDBCDriver newDriver = JDBCDriver.create(driverName, driverDisplayName, driverClass, driverFileUrls); - JDBCDriverManager.getDefault().addDriver(newDriver); + if (driverClassFound) { + JDBCDriver newDriver = JDBCDriver.create(driverName, driverDisplayName, driverClass, driverFileUrls); + JDBCDriverManager.getDefault().addDriver(newDriver); + } } catch (MalformedURLException e) { LOGGER.log(Level.WARNING, null, e); } catch (DatabaseException e) { @@ -332,6 +343,20 @@ private static void registerDriver(String driverName, String driverDisplayName, } } + private static boolean containsClass(File file, String className) { + String relativePath = className.replace(".", "/") + ".class"; + if(file.isFile()) { + try (JarFile jf = new JarFile(file)) { + return jf.getEntry(relativePath) != null; + } catch (IOException ex) { + // Ok, ignore + } + } else if (file.isDirectory()) { + return new File(file, relativePath).exists(); + } + return false; + } + private void registerLibrary(final String newLocation) { final FileObject libsFolder = FileUtil.getConfigFile( "org-netbeans-api-project-libraries/Libraries"); //NOI18N diff --git a/ide/derby/src/org/netbeans/modules/derby/ExecSupport.java b/ide/derby/src/org/netbeans/modules/derby/ExecSupport.java index 9aa693519366..8cf26aa98cba 100644 --- a/ide/derby/src/org/netbeans/modules/derby/ExecSupport.java +++ b/ide/derby/src/org/netbeans/modules/derby/ExecSupport.java @@ -282,7 +282,7 @@ public void finishLoop() { @Override public void run() { - while (loop) { + while (loop && child.isAlive()) { if (isStringFound()) { status = true; break; diff --git a/ide/derby/src/org/netbeans/modules/derby/RegisterDerby.java b/ide/derby/src/org/netbeans/modules/derby/RegisterDerby.java index 22f8c7c467bc..a4440a01eb9f 100644 --- a/ide/derby/src/org/netbeans/modules/derby/RegisterDerby.java +++ b/ide/derby/src/org/netbeans/modules/derby/RegisterDerby.java @@ -77,7 +77,8 @@ public class RegisterDerby implements DatabaseRuntime { private static final int START_TIMEOUT = 0; // seconds - private static RegisterDerby reg=null; + private static RegisterDerby reg = null; + private static DatabaseRuntime regModular = null; /** Derby server process */ private static Process process = null; @@ -85,9 +86,9 @@ public class RegisterDerby implements DatabaseRuntime { /** Creates a new instance of RegisterDerby */ private RegisterDerby() {} - public static synchronized RegisterDerby getDefault(){ - if (reg==null) { - reg= new RegisterDerby(); + public static synchronized RegisterDerby getDefault() { + if (reg == null) { + reg = new RegisterDerby(); if (EventQueue.isDispatchThread()) { // #229741 RequestProcessor.getDefault().post(new Runnable() { @@ -102,7 +103,45 @@ public void run() { } return reg; } - + + public static synchronized DatabaseRuntime getModular() { + if (regModular == null) { + RegisterDerby mainRuntime = getDefault(); + regModular = new DatabaseRuntime() { + @Override + public String getJDBCDriverClass() { + return DerbyOptions.DRIVER_CLASS_NET_MODULAR; + } + + @Override + public boolean acceptsDatabaseURL(String url) { + return mainRuntime.acceptsDatabaseURL(url); + } + + @Override + public boolean isRunning() { + return mainRuntime.isRunning(); + } + + @Override + public boolean canStart() { + return mainRuntime.canStart(); + } + + @Override + public void start() { + mainRuntime.start(); + } + + @Override + public void stop() { + mainRuntime.stop(); + } + }; + } + return regModular; + } + /** * Whether this runtime accepts this connection string. */ @@ -158,17 +197,6 @@ private String getNetworkServerClasspath() { Util.getDerbyFile("lib/derbynet.jar").getAbsolutePath(); // NOI18N } - /** - * Returns the registered Derby driver. - */ - private JDBCDriver getRegisteredDerbyDriver() { - JDBCDriver[] drvs = JDBCDriverManager.getDefault().getDrivers(DerbyOptions.DRIVER_CLASS_NET); - if (drvs.length > 0) { - return drvs[0]; - } - return null; - } - public int getPort() { return 1527; } @@ -377,7 +405,10 @@ public void doNotShowAgainClicked() { private String startArgs() { Preferences prefs = NbPreferences.forModule(RegisterDerby.class); - if (prefs.getBoolean(DISABLE_SECURITY_MANAGER, false)) { + + boolean disableSecurityManager = Integer.getInteger("java.specification.version", -1) > 17; + + if (prefs.getBoolean(DISABLE_SECURITY_MANAGER, false) || disableSecurityManager) { return " -noSecurityManager"; //NOI18N } else { return ""; //NOI18N diff --git a/ide/derby/src/org/netbeans/modules/derby/layer.xml b/ide/derby/src/org/netbeans/modules/derby/layer.xml index 47200dff6ff0..5d92362b1d6a 100644 --- a/ide/derby/src/org/netbeans/modules/derby/layer.xml +++ b/ide/derby/src/org/netbeans/modules/derby/layer.xml @@ -38,6 +38,10 @@ + + + + diff --git a/java/j2ee.persistence/src/org/netbeans/modules/j2ee/persistence/wizard/fromdb/DatabaseTablesPanel.java b/java/j2ee.persistence/src/org/netbeans/modules/j2ee/persistence/wizard/fromdb/DatabaseTablesPanel.java index 0c77b6ed908c..5e91ed5a7c70 100644 --- a/java/j2ee.persistence/src/org/netbeans/modules/j2ee/persistence/wizard/fromdb/DatabaseTablesPanel.java +++ b/java/j2ee.persistence/src/org/netbeans/modules/j2ee/persistence/wizard/fromdb/DatabaseTablesPanel.java @@ -349,7 +349,7 @@ private static List findDatabaseConnections(JPADataSource da String databaseUrl = datasource.getUrl(); String user = datasource.getUsername(); for (DatabaseConnection dbconn : ConnectionManager.getDefault().getConnections()) { - if (databaseUrl.equals(dbconn.getDatabaseURL())) { + if (Objects.equals(databaseUrl, dbconn.getDatabaseURL())) { result.add(dbconn); } }