Traccar 6.7.1 and Oracle 19c

Number42 7 months 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 Tananaev 7 months ago

What's the reason for using Oracle?

Number42 7 months 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 Tananaev 7 months ago

Can you provide JDBC details for testing?

Number42 7 months 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 Tananaev 7 months ago

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

Number42 7 months ago

Where to send login credentials and zip file ?

Anton Tananaev 7 months ago

You can send to the support email address.

Number42 7 months ago

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

Number42 7 months ago

Sending

Version DB 23i

Number42 7 months 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 Tananaev 7 months ago

You can set default group, but not user.

Number42 7 months 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 Tananaev 7 months ago

I recommend reading documentation first before asking for help.

Number42 7 months 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