Traccar 6.7.1 and Oracle 19c

Number42a month ago

Hi. Try to install traccar
Platform : Traccar running on VM Oracle Cloud (oracle linux 8.6) 1 CPU , 1GB memory.
Database: Oracle 19c on Oracle cloud (ATP) with mTLS connection.
Driver: ojdbc17-full

1.

2025-06-01 16:31:36 ERROR: Main method error - Unable to make void jdk.internal.loader.ClassLoaders$AppClassLoader.appendToClassPathForInstrumentation(java.lang.String) accessible: module java.base does not "opens jdk.internal.loader" to unnamed module @229f66ed - InaccessibleObjectException (... < DatabaseModule:57 < <gener:-1 < *:-1 < ... < MainModule:141 < <gener:-1 < ...)
2025-06-01 16:31:36 DEBUG: Runtime.exit() called with status: 1 - Runtime.exit(1) - Throwable (... < Main:154 < *:111)

add --add-opens=java.base/jdk.internal.loader=ALL-UNNAMED start option

2025-05-30 09:20:26 DEBUG: Failed to create or initialize the lock table, trying again, iteration 9 of 10 - ORA-12838: cannot
 read/modify an object after modifying it in parallel  - OracleDatabaseException (... < DatabaseModule:98 < <gener:-1 < *:-1 < ... < MainModule:141 < <gener:-1 < ...)
2025-05-30 09:20:27 DEBUG: Changelog query completed.
2025-05-30 09:20:27 DEBUG: Initialize Database Lock Table
2025-05-30 09:20:27 DEBUG: DELETE FROM VEHICLES_TRACCAR.DATABASECHANGELOGLOCK
2025-05-30 09:20:27 DEBUG: 0 row(s) affected

manual INSERT INTO VEHICLES_TRACCAR.DATABASECHANGELOGLOCK (ID, LOCKED) VALUES (1, 0)

2025-05-30 15:59:58 DEBUG: No default value for SameSite
2025-05-30 15:59:58 DEBUG: Starting mapping of the exception. - ORA-00933: SQL command not properly ended
 - OracleDatabaseException (... < QueryBuilder:413 < DatabaseStorage:76 < UserUtil:37 < ServerResource:109 < ...)
2025-05-30 15:59:58 DEBUG: Exception 'java.sql.SQLSyntaxErrorException: ORA-00933: SQL command not properly ended

https://docs.oracle.com/error-help/db/ora-00933/' has been mapped by 'org.traccar.api.ResourceErrorHandler' to respons
e 'Bad Request' (400:CLIENT_ERROR).

get sources and edit DatabaseStorage.java

            if (order.getLimit() > 0) {
                if (databaseType.equals("Microsoft SQL Server")) {
                    result.append(" OFFSET 0 ROWS FETCH FIRST ");
                    result.append(order.getLimit());
                    result.append(" ROWS ONLY");
                } else if (databaseType.equals("Oracle")) {
                    result.append(" FETCH FIRST ");
                    result.append(order.getLimit());
                    result.append(" ROWS ONLY");
                } else {
                    result.append(" LIMIT ");
                    result.append(order.getLimit());
                }
            }
2025-05-31 17:47:26  INFO: SELECT id FROM tc_users ORDER BY id FETCH FIRST 1 ROWS ONLY
2025-05-31 17:47:26  INFO: SELECT * FROM tc_servers
2025-05-31 17:47:26  INFO: INSERT INTO tc_users(map, login, totpKey, latitude, longitude, phone, disabled, expirationTime, readonly, deviceReadonly, zoom, coordinateFormat, limitCommands, disableReports, fixedEmail, poiLayer, email, administrator, deviceLimit, userLimit, temporary, name, attributes) VALUES (:map, :login, :totpKey, :latitude, :longitude, :phone, :disabled, :expirationTime, :readonly, :deviceReadonly, :zoom, :coordinateFormat, :limitCommands, :disableReports, :fixedEmail, :poiLayer, :email, :administrator, :deviceLimit, :userLimit, :temporary, :name, :attributes)
2025-05-31 17:47:26 DEBUG: Starting mapping of the exception. - Character A is neither a decimal digit number, decimal point, nor
 "e" notation exponential mark. - NumberFormatException (... < QueryBuilder:473 < DatabaseStorage:100 < UserResource:120 < ..
. <OverrideFilter:50 < ...)
2025-05-31 17:47:26 DEBUG: Exception 'java.sql.SQLException: ORA-17132: Invalid conversion requested

Oracle return ROWID not ID

edit QueryBuilder.java

//                    statement = connection.prepareStatement(parsedQuery, Statement.RETURN_GENERATED_KEYS);
                    statement = connection.prepareStatement(parsedQuery, new String[] { "ID" });

On this point Web Traccar work, Administarator registered

Current error :

2025-06-01 14:42:13  INFO: SELECT * FROM tc_devices WHERE id IN (SELECT tc_user_device.deviceId FROM tc_user_device WHERE userId = :userId UNION SELECT DISTINCT deviceId FROM tc_user_group INNER JOIN (SELECT id as parentId, id as groupId FROM tc_groups UNION SELECT groupId as parentId, id as groupId FROM tc_groups WHERE groupId IS NOT NULL UNION SELECT g2.groupId as parentId, g1.id as groupId FROM tc_groups AS g2 INNER JOIN tc_groups AS g1 ON g2.id = g1.groupId WHERE g2.groupId IS NOT NULL) AS all_groups ON tc_user_group.groupId = all_groups.parentId INNER JOIN (SELECT groupId as parentId, id as deviceId FROM tc_devices WHERE groupId IS NOT NULL) AS devices ON all_groups.groupId = devices.parentId WHERE userId = :userId) ORDER BY name
2025-06-01 14:42:13 DEBUG: Starting mapping of the exception. - ORA-00907: missing right parenthesis
 - OracleDatabaseException (... < QueryBuilder:414 < DatabaseStorage:81 < DeviceResource:141 < ... < OverrideFilter:50 < ...)
2025-06-01 14:42:13 DEBUG: Exception 'java.sql.SQLSyntaxErrorException: ORA-00907: missing right parenthesis

Haw to disable Group functioal ? Or help rewrite code .

Anton Tananaeva month ago

What's the reason for using Oracle?

Number42a month ago

Oracle RDBMS latest version on cloud - cost = $0, maintenance time - 0 sec.
I am Oracle PL/SQL Developer.
In current project need server getting mesages from tracing devices and store on DB

Anton Tananaeva month ago

Can you provide JDBC details for testing?

Number42a month ago

Config xml:

    <entry key='database.driverFile'>/opt/traccar/lib/ojdbc17.jar</entry>
    <entry key="database.driver">oracle.jdbc.OracleDriver</entry>
    <entry key='database.url'>jdbc:oracle:thin:@ApexDev19c_medium?TNS_ADMIN=/opt/oracle/db_conn/ApexDev19c</entry>
    <entry key='database.user'>VEHICLES_TRACCAR</entry>
    <entry key='database.password'>password</entry>

    <entry key='database.checkConnection'>SELECT 1 FROM DUAL</entry>
    <entry key='logger.queries'>true</entry>

/opt/oracle/db_conn/ApexDev19c - Dir unziped sertificates from cloud DB
You need connect to my DB ?

Anton Tananaeva month ago

I need a real database. It doesn't have to be your production DB.

Number42a month ago

Where to send login credentials and zip file ?

Anton Tananaeva month ago

You can send to the support email address.

Number42a month ago

Ok. I will prepare test DB for You and send to support email.
Thank you

Number42a month ago

Sending

Version DB 23i

Number42a month ago

comment Group query
UNION ... JOUN ... JOIN ... UNION ...

SELECT g2.groupId as parentId, g1.id as groupId FROM tc_groups AS g2
INNER JOIN tc_groups AS g1 ON g2.id = g1.groupId

set false flag Statement.RETURN_GENERATED_KEYS on addPermission and removePermission.
Return Primary Key from DELETE query ?

Add device from web work
Add unregister device - work.

How to set default UserID on <entry key='database.registerUnknown'>true</entry> ?

Anton Tananaeva month ago

You can set default group, but not user.

Number42a month ago

What is the point Groups ? In table Devices present column GroupID , but not present UserID.
Why Groups with recursion ? (self-recursion)
What is relation Devices-Groups-Users ?

Anton Tananaeva month ago

I recommend reading documentation first before asking for help.

Number42a month ago

In documentation writed how to rewrite thi code :

  /*  if (condition.getIncludeGroups()) {

            boolean expandDevices;
            String groupStorageName;
            if (GroupedModel.class.isAssignableFrom(condition.getOwnerClass())) {
                expandDevices = Device.class.isAssignableFrom(condition.getOwnerClass());
                groupStorageName = Permission.getStorageName(Group.class, condition.getPropertyClass());
            } else {
                expandDevices = Device.class.isAssignableFrom(condition.getPropertyClass());
                groupStorageName = Permission.getStorageName(condition.getOwnerClass(), Group.class);
            }

            result.append(" UNION ");

            result.append("SELECT DISTINCT ");
            if (!expandDevices) {
                if (outputKey.equals("groupId")) {
                    result.append("all_groups.");
                } else {
                    result.append(groupStorageName).append('.');
                }
            }
            result.append(outputKey);
            result.append(" FROM ");
            result.append(groupStorageName);

            result.append(" INNER JOIN (");
            result.append("SELECT id as parentId, id as groupId FROM ");
            result.append(getStorageName(Group.class));
            result.append(" UNION ");
            result.append("SELECT groupId as parentId, id as groupId FROM ");
            result.append(getStorageName(Group.class));
            result.append(" WHERE groupId IS NOT NULL");
            result.append(" UNION ");
            result.append("SELECT g2.groupId as parentId, g1.id as groupId FROM ");
            result.append(getStorageName(Group.class));
            result.append(" AS g2");
            result.append(" INNER JOIN ");
            result.append(getStorageName(Group.class));
            result.append(" AS g1 ON g2.id = g1.groupId");
            result.append(" WHERE g2.groupId IS NOT NULL");
            result.append(") AS all_groups ON ");
            result.append(groupStorageName);
            result.append(".groupId = all_groups.parentId");

            if (expandDevices) {
                result.append(" INNER JOIN (");
                result.append("SELECT groupId as parentId, id as deviceId FROM ");
                result.append(getStorageName(Device.class));
                result.append(" WHERE groupId IS NOT NULL");
                result.append(") AS devices ON all_groups.groupId = devices.parentId");
            }

            result.append(" WHERE ");
            result.append(conditionKey);
            result.append(" = :");
            result.append(conditionKey);

        } */

?
Table TC_GROUPS recursive (tree) , but query is not recursive