@@ -65,10 +65,31 @@ public final class SyncClientImpl implements SyncClient {
6565 this .serverUrl = builder .serverUrl ();
6666 this .connectivityMonitor = builder .platform .getConnectivityMonitor ();
6767
68- long boxStoreHandle = builder .boxStore .getNativeStore ();
69- long handle = nativeCreate (boxStoreHandle , serverUrl , builder .trustedCertPaths );
68+ // Build the options
69+ long optHandle = nativeSyncOptCreate (builder .boxStore .getNativeStore ());
70+ if (optHandle == 0 ) {
71+ throw new RuntimeException ("Failed to create Sync client options: handle is zero." );
72+ }
73+ try {
74+ // Add server URL
75+ nativeSyncOptAddUrl (optHandle , serverUrl );
76+
77+ // Add trusted certificate paths if provided
78+ if (builder .trustedCertPaths != null ) {
79+ for (String certPath : builder .trustedCertPaths ) {
80+ nativeSyncOptAddCertPath (optHandle , certPath );
81+ }
82+ }
83+ } catch (Exception e ) {
84+ // Free the options if any option method call failed (like due to invalid arguments)
85+ nativeSyncOptFree (optHandle );
86+ throw e ;
87+ }
88+
89+ // Create the sync client (this frees the options in any case)
90+ long handle = nativeSyncOptCreateClient (optHandle );
7091 if (handle == 0 ) {
71- throw new RuntimeException ("Failed to create sync client: handle is zero." );
92+ throw new RuntimeException ("Failed to create Sync client: handle is zero." );
7293 }
7394 this .handle = handle ;
7495
@@ -356,10 +377,61 @@ public ObjectsMessageBuilder startObjectsMessage(long flags, @Nullable String to
356377 }
357378
358379 /**
359- * Creates a native sync client for the given store handle ready to connect to the server at the given URI.
360- * Uses certificate authorities trusted by the host if no trusted certificate paths are passed.
380+ * Creates a sync client options object for the given store.
381+ * <p>
382+ * The options must be configured (at least one URL) and then used with {@link #nativeSyncOptCreateClient}.
383+ *
384+ * @return handle to the options object, or 0 on error
385+ */
386+ private static native long nativeSyncOptCreate (long storeHandle );
387+
388+ /**
389+ * Adds a server URL to the sync options; at least one URL must be added before creating the sync client.
390+ * <p>
391+ * Passing multiple URLs allows high availability and load balancing (i.e. using an ObjectBox Sync Server Cluster).
392+ * <p>
393+ * A random URL is selected for each connection attempt.
394+ */
395+ private static native void nativeSyncOptAddUrl (long optHandle , String url );
396+
397+ /**
398+ * Adds a certificate path to the sync options.
399+ * <p>
400+ * This allows to pass certificate paths referring to the local file system.
401+ * <p>
402+ * Example use cases are using self-signed certificates in a local development environment and custom certificate
403+ * authorities.
404+ */
405+ private static native void nativeSyncOptAddCertPath (long optHandle , String certPath );
406+
407+ /**
408+ * Sets sync flags to adjust sync behavior; see SyncFlags for available flags.
409+ * <p>
410+ * Combine multiple flags using bitwise OR.
411+ */
412+ private static native void nativeSyncOptFlags (long optHandle , int flags );
413+
414+ /**
415+ * Creates a sync client with the given options.
416+ * <p>
417+ * This does not initiate any connection attempts yet: call {@link #nativeStart} to do so. Before nativeStart(), you
418+ * must configure credentials via {@link #nativeSetLoginInfo} or {@link #nativeAddLoginCredentials}.
419+ * <p>
420+ * By default, a sync client automatically receives updates from the server once login succeeded. To configure this
421+ * differently, call {@link #nativeSetRequestUpdatesMode} with the wanted mode.
422+ * <p>
423+ * Note: the given options are always freed by this function, including when an error occurs.
424+ *
425+ * @return handle to the sync client, or 0 on error
426+ */
427+ private static native long nativeSyncOptCreateClient (long optHandle );
428+
429+ /**
430+ * Frees the sync options object.
431+ * <p>
432+ * Note: Only free *unused* options; {@link #nativeSyncOptCreateClient} frees the options internally.
361433 */
362- private static native long nativeCreate (long storeHandle , String uri , @ Nullable String [] certificateDirsOrPaths );
434+ private static native void nativeSyncOptFree (long optHandle );
363435
364436 private native void nativeDelete (long handle );
365437
0 commit comments