I write a test to try to make freeplane work with mysql, but it failed.
code:
import groovy.sql.Sql
def url = "jdbc:mysql://localhost:3306/mindmap"
def user = "root"
def password = "root"
def driver = "com.mysql.jdbc.Driver"
def sql = Sql.newInstance(url, user, password, driver)
sql.execute """
CREATE TABLE Author (
id INTEGER,
firstName VARCHAR(64),
lastName VARCHAR(64)
);
"""
sql.close()
exception:
STDOUT: Mar 05, 2022 12:18:32 AM org.freeplane.core.util.LogUtils warn
WARNING: ExecuteScriptAction failed:
java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/mindmap
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:702)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:228)
at groovy.sql.Sql.newInstance(Sql.java:396)
at groovy.sql.Sql.newInstance(Sql.java:437)
at groovy.sql.Sql$newInstance.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:166)
at common.run(common.groovy:22)
at org.freeplane.plugin.script.GroovyScript.execute(GroovyScript.java:112)
at org.freeplane.plugin.script.ScriptRunner.execute(ScriptRunner.java:56)
at org.freeplane.plugin.script.ExecuteScriptAction.actionPerformed(ExecuteScriptAction.java:112)
at java.desktop/javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1810)
at org.freeplane.core.ui.ActionAcceleratorManager.processKeyBinding(ActionAcceleratorManager.java:440)
at org.freeplane.main.mindmapmode.MModeControllerFactory$2.processKeyBinding(MModeControllerFactory.java:288)
at org.freeplane.view.swing.ui.UserInputListenerFactory$2.processKeyBinding(UserInputListenerFactory.java:172)
at org.freeplane.core.ui.components.FreeplaneMenuBar.processKeyBinding(FreeplaneMenuBar.java:116)
at org.freeplane.main.application.MenuKeyProcessor.processKeyBinding(MenuKeyProcessor.java:26)
at org.freeplane.main.application.ConnectedToMenuView.processKeyBinding(ConnectedToMenuView.java:41)
at java.desktop/javax.swing.JComponent.processKeyBindings(JComponent.java:2962)
at java.desktop/javax.swing.JComponent.processKeyEvent(JComponent.java:2862)
at java.desktop/java.awt.Component.processEvent(Component.java:6412)
at java.desktop/java.awt.Container.processEvent(Container.java:2263)
at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5011)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4843)
at java.desktop/java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1950)
at java.desktop/java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:870)
at java.desktop/java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1139)
at java.desktop/java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:1009)
at java.desktop/java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:835)
at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4892)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2772)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4843)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:743)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
but it worked in idea's Groovy Console. I want to know where goes wrong.
Just a though: is the mysql jdbc driver on your classpath when you try to run it from within Freeplane?
sure, I put it in class path, did it work for you?
Last edit: peter 2022-03-05
Where have you put the jar file?
Have you tried to put it into
<freeplane-user-config>/1.9.x/lib
?sorry, late for replying. like macmarrum mentioned, datasource is a solution, and I will also test your suggestion sometime. thanks for replying.
I just have a nice idea and was about to put a request, and found that I was forbidden to create new ticket, I don't know what's wrong with it, did I make a mistake or something?
if yes, I am sorry and please let me know, I will avoid making to this.
Thanks.
Could you please open the new ticket at https://github.com/freeplane/freeplane/issues ?
no problem, sorry for missing the announcement.
I have tried with sqlite-jdbc-3.36.0.3.jar, puting the driver in
<freeplane-user-config>/1.9.x/lib
. There seems to be a more generic issue around JDBCLast edit: macmarrum 2022-03-13
The problem comes with a combination of dynamic features by Groovy and Class Loaders.
I can not fix it but I can suggest a workaround:
Try to wrap calls to
Sql.newInstance(url, user, password, driver)
andDriverManager.getConnection
in a similar wayThanks, Dimitry.
I was unsuccessful wrapping
Sql.newInstance
this way.I suppose
DriverManager.getConnection
could be used instead. But apart from it being a bit cumbersome as compared togroovy.sql.Sql
, with@CompileStatic
the code seems to loose the ability to interact with the map/nodes.What I did instead was to add
sqlite-jdbc-3.36.0.3.jar
to classpath for Java, by copying the jar to<freeplane-install-dir>
and modifyingfreeplanelauncher.jar#META-INF/MANIFEST.MF
:This has registered the driver correctly with the DriverManager and
groovy.sql.Sql
worked as expected. But I ran into access denied. To allow the sqlite driver to work (for the in-memory database case), I had to extend<freeplane-install-dir>/freeplane.policy
, adding:Last edit: macmarrum 2022-03-13
I have checked only the DriverManager.
I would wrap into the helper class only the call to getConnection keeping the rest unchanged.
Success 📯 😄 🙌
Whereas
SQL.newInstance
fails, creating anew Sql
by providing aDataSource
succeeds.Here's a working example for MariaDB -- I put
mariadb-java-client-3.0.3.jar
in<freeplane-user-config>/1.9.x/lib