B4J Question jRDC Server works when run from IDE, but fails when run from the package build

rgarnett1955

Active Member
Licensed User
Longtime User
Hi,

I have a jRDC server that I want to run headless from the command line:

If I run it from the IDE it works fine, my client connects and gets data from my sqLite DB.

However if I make a stand alone package and run the .exe file from a shortcut it starts, but I can't get data into the client.

The command window that the jRDC server is running in has the following error: Could Not load Driver class com.sqlite.jdbcUrl

My server Main file is:

Server Main Code:
'Non-UI application (console / server application)
#Region  Project Attributes
'    #AdditionalJar: sqlite-jdbc-3.30.1
'    #AdditionalJar: sqlite-jdbc-3.7.2
    #AdditionalJar: sqlite-jdbc-3.36.0.3
'    #AdditionalJar: sqlite-jdbc-3.43.2.0
'    #CommandLineArgs: "Port_17200_ShorttClock.properties"
    #MergeLibraries: True
#End Region

'change based on the jdbc jar file
'#AdditionalJar: mysql-connector-java-5.1.27-bin
'#AdditionalJar: postgresql-9.4.1207

Sub Process_Globals
    Public srvr As Server
    Public rdcConnector1 As RDCConnector
    Public const VERSION As Float = 2.23
    Type DBCommand (Name As String, Parameters() As Object)
    Type DBResult (Tag As Object, Columns As Map, Rows As List)
    
    Public IPAddress As String
    Public configMapFileArg As String
    Public dirString As String
End Sub

Sub AppStart (Args() As String)
    Dim configMap As Map
    
'    If Args.Length <> 1 Then
'        Return
'    End If
    
'    'Get the configMap filename arg
'    Try
'        configMapFileArg = Args(0)
'    Catch
'        Return
'    End Try

    configMap = File.ReadMap(File.DirAssets, "Port_17200_ShorttClock.properties")
    
    If configMap.Size = 0 Then
        Return
    End If

    srvr.Initialize("")
    rdcConnector1.Initialize(configMap)
    srvr.Port = rdcConnector1.serverPort
    srvr.AddHandler("/test", "TestHandler", False)
    srvr.AddHandler("/rdc", "RDCHandler", False)
    srvr.Start
    Log($"jRDC is running (version = $1.2{VERSION})"$)
    Log("IP Addr = " & configMap.Get("IPAddress") & "  Port = " & srvr.Port)
    Log("JdbcUrl = " & configMap.Get("JdbcUrl"))
    StartMessageLoop
End Sub


The command window output is:

Erro: Can't load driver class:
SLF4J: No SLF4J providers were found.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#noProviders for further details.
MLog initialization issue: slf4j found no binding or threatened to use its (dangerously silent) NOPLogger. We consider the slf4j library not found.
Oct 19, 2023 5:29:26 PM com.mchange.v2.log.MLog
INFO: MLog clients using java 1.4+ standard logging.
Oct 19, 2023 5:29:26 PM com.mchange.v2.c3p0.C3P0Registry
INFO: Initializing c3p0-0.9.5.2 [built 08-December-2015 22:06:04 -0800; debug? true; trace: 10]
jRDC is running (version = 2.23)
IP Addr = 192.168.1.114  Port = 17200
JdbcUrl = jdbc:sqlite:G:\shorttClockTestDB\shorttClockTestDB.sqlite3
Oct 19, 2023 5:29:41 PM com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource
INFO: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 20000, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> 1hgeby9azjlg6hy1jss0br|64f6106c, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.sqlite.JdbcUrl, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 1hgeby9azjlg6hy1jss0br|64f6106c, idleConnectionTestPeriod -> 600, initialPoolSize -> 3, jdbcUrl -> jdbc:sqlite:G:\shorttClockTestDB\shorttClockTestDB.sqlite3, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 1800, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 15, maxStatements -> 150, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {password=******, user=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> true, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]
Oct 19, 2023 5:29:41 PM com.mchange.v2.c3p0.DriverManagerDataSource
WARNING: Could not load driverClass com.sqlite.JdbcUrl
java.lang.ClassNotFoundException: com.sqlite.JdbcUrl
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
        at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
        at java.base/java.lang.Class.forName0(Native Method)
        at java.base/java.lang.Class.forName(Unknown Source)
        at b4j/com.mchange.v2.c3p0.DriverManagerDataSource.ensureDriverLoaded(Unknown Source)
        at b4j/com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(Unknown Source)
        at b4j/com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(Unknown Source)
        at b4j/com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(Unknown Source)
        at b4j/com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(Unknown Source)
        at b4j/com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(Unknown Source)
        at b4j/com.mchange.v2.resourcepool.BasicResourcePool.doAcquireAndDecrementPendingAcquiresWithinLockOnSuccess(Unknown Source)
        at b4j/com.mchange.v2.resourcepool.BasicResourcePool.access$700(Unknown Source)
        at b4j/com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask.run(Unknown Source)
        at b4j/com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(Unknown Source)


Can anyone help with this.

I'm also uncertain which sqlite-jdbc-x.x.x to use.

Regards
Rob
 

aeric

Expert
Licensed User
Longtime User
Is this work for you?


B4X:
#AdditionalJar: sqlite-jdbc-3.39.3.0
 
Upvote 0

rgarnett1955

Active Member
Licensed User
Longtime User
1. It isn't recommended to use SQLite with connection pool. You will corrupt th
Modded jRDC2 w/SQLite support and more
[WebApp] Concurrent access to SQLite databases

2. The error itself happens because the jdbc driver isn't compatible with the packager.
Hi Erel,

I'm only using the jRRDC server to read from the DB so using sqLite this way isn't a problem. I would never have two apps trying to write to sqLite at the same time. Bad idea. My db gets written to by another app that reads data over WiFi from an embedded system and writes directly to the DB without using jRDC. I have a couple of embedded systems using this architecture.


I thought that I had used jRDC in packaged versions before, but that was twelve months ago so perhaps something has changed or more likely my memory fails me. Chris2 also says that he has jRDC working with the packager.

Looking at the error I'm sure you are correct.


I will just have to run the server from the jar file.

Thanks for your help
Regards
Rob
 
Upvote 0

rgarnett1955

Active Member
Licensed User
Longtime User
is that correct?
I have a jRDC2 based app (based on @OliverA's Modded jRDC2 w/SQLite support) using sqlite-jdbc-3.34.0 that seems to be fine when packaged with the internal packager.
Hi Chris,

Its strange because I thought I had jRDC working with sqLite in packaged form about 12 months ago, but I'm not 100% sure, I could have been running the release from the jar file.

I will give OliverA's code a try and see what happens.

Best regards
Rob
 
Upvote 0

rgarnett1955

Active Member
Licensed User
Longtime User
is that correct?
I have a jRDC2 based app (based on @OliverA's Modded jRDC2 w/SQLite support) using sqlite-jdbc-3.34.0 that seems to be fine when packaged with the internal packager.
Hi Chris,

Its strange because I thought I had jRDC working with sqLite in packaged form about 12 months ago, but I'm not 100% sure, I could have been running the release from the jar file.

I will give OliverA's code a try and see what happens.

Best regards
Rob


Hello again Chris,

I gave OliverA's code a whirl with the packager and voila, it works fine.

I get the following message in the command box:

SLF4J: No SLF4J providers were found.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#noProviders for further details.
Modified jRDC is running (version = 2.22)
Note: jRDC is running without V1 support
Bound to: 192.168.1.114:17200
Command: query: getLast10MinCounter720Hour, took: 82ms, client=192.168.1.114

There must be some sort of special magic in OliverA's code. Being a rather ordinary embedded C programmer I find all this java stuff beyond me.

So I will use this version.

I like the jRDC thingy it makes remote access to my embedded systems data a breeze.

Thanks for that!

Regards
Rob
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
It seems the problem is raised by the latest sqlite-jdbc library version 3.43.2.0+

 
Upvote 0

Chris2

Active Member
Licensed User
It seems the problem is raised by the latest sqlite-jdbc library version 3.43.2.0+

Well spotted @aeric & @drgottjr!

There must be some sort of special magic in OliverA's code.
As I understand it, @OliverA's modded jRDC2 recognises if an SQLite driver is in use and does not use a connection pool in that case. It sets the SQlite to wal mode (which allows only one writter but multiple readers to connect at a time I think) and uses a single SQL connection (not a pool). Write requests are queued up to be executed in turn - only one at a time.
So yeah, basically it uses magic to handle the database connection for you so you can fire whatever you like at the jRDC2 server and not worry about it :) (provided they haven't broken something in the jdbc driver of course!).
 
Upvote 0
Top