Skip to content

Commit 6f34fc5

Browse files
committed
Complete nullability info in GDS-ng and implementations
1 parent ccde651 commit 6f34fc5

130 files changed

Lines changed: 1084 additions & 783 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

jaybird-native/src/main/java/org/firebirdsql/gds/ng/jna/AbstractNativeDatabaseFactory.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
// SPDX-FileCopyrightText: Copyright 2014-2024 Mark Rotteveel
1+
// SPDX-FileCopyrightText: Copyright 2014-2026 Mark Rotteveel
22
// SPDX-License-Identifier: LGPL-2.1-or-later
33
package org.firebirdsql.gds.ng.jna;
44

55
import com.sun.jna.NativeLibrary;
66
import org.firebirdsql.gds.JaybirdErrorCodes;
77
import org.firebirdsql.gds.ng.*;
88
import org.firebirdsql.jna.fbclient.FbClientLibrary;
9+
import org.jspecify.annotations.Nullable;
910

1011
import java.nio.file.Files;
1112
import java.nio.file.InvalidPathException;
@@ -28,7 +29,7 @@
2829
public abstract class AbstractNativeDatabaseFactory implements FbDatabaseFactory {
2930

3031
private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
31-
private FbClientResource resource;
32+
private @Nullable FbClientResource resource;
3233

3334
@Override
3435
public JnaDatabase connect(IConnectionProperties connectionProperties) throws SQLException {
@@ -179,7 +180,7 @@ private void configureSearchPath(IAttachProperties<?> connectionProperties) {
179180
}
180181
}
181182

182-
private String resolvePathForJna(String nativeLibraryPath) {
183+
private @Nullable String resolvePathForJna(String nativeLibraryPath) {
183184
var log = System.getLogger(getClass().getName());
184185
try {
185186
Path actualPath = Path.of(nativeLibraryPath).toAbsolutePath();

jaybird-native/src/main/java/org/firebirdsql/gds/ng/jna/FbClientFeatureAccessHandler.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: Copyright 2019-2023 Mark Rotteveel
1+
// SPDX-FileCopyrightText: Copyright 2019-2026 Mark Rotteveel
22
// SPDX-License-Identifier: LGPL-2.1-or-later
33
package org.firebirdsql.gds.ng.jna;
44

@@ -79,12 +79,11 @@ static FbClientLibrary decorateWithFeatureAccess(FbClientLibrary library) {
7979
"Could not decorate client library with FbClientFeatureAccess: not a proxy");
8080
}
8181
InvocationHandler ih = Proxy.getInvocationHandler(library);
82-
if (!(ih instanceof Library.Handler)) {
82+
if (!(ih instanceof Library.Handler originalHandler)) {
8383
throw new IllegalArgumentException("Could not decorate client library with FbClientFeatureAccess: "
8484
+ "unexpected invocation handler type " + ih.getClass());
8585
}
8686

87-
Library.Handler originalHandler = (Library.Handler) ih;
8887
NativeLibrary nativeLibrary = originalHandler.getNativeLibrary();
8988
Set<FbClientFeature> clientFeatures = determineClientFeatures(nativeLibrary);
9089

jaybird-native/src/main/java/org/firebirdsql/gds/ng/jna/FbClientResource.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
// SPDX-FileCopyrightText: Copyright 2019-2025 Mark Rotteveel
1+
// SPDX-FileCopyrightText: Copyright 2019-2026 Mark Rotteveel
22
// SPDX-License-Identifier: LGPL-2.1-or-later
33
package org.firebirdsql.gds.ng.jna;
44

55
import com.sun.jna.NativeLibrary;
66
import org.firebirdsql.jaybird.util.Cleaners;
77
import org.firebirdsql.jna.fbclient.FbClientLibrary;
8+
import org.jspecify.annotations.Nullable;
89

910
import java.lang.System.Logger.Level;
1011
import java.lang.ref.Cleaner;
@@ -24,7 +25,7 @@
2425
final class FbClientResource extends NativeResourceTracker.NativeResource {
2526

2627
@SuppressWarnings("java:S3077")
27-
private volatile FbClientLibrary library;
28+
private volatile @Nullable FbClientLibrary library;
2829
private final AbstractNativeDatabaseFactory owner;
2930
private final Cleaner.Cleanable cleanable;
3031

jaybird-native/src/main/java/org/firebirdsql/gds/ng/jna/JnaBlob.java

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: Copyright 2014-2025 Mark Rotteveel
1+
// SPDX-FileCopyrightText: Copyright 2014-2026 Mark Rotteveel
22
// SPDX-License-Identifier: LGPL-2.1-or-later
33
package org.firebirdsql.gds.ng.jna;
44

@@ -15,6 +15,7 @@
1515
import org.firebirdsql.jaybird.util.ByteArrayHelper;
1616
import org.firebirdsql.jna.fbclient.FbClientLibrary;
1717
import org.firebirdsql.jna.fbclient.ISC_STATUS;
18+
import org.jspecify.annotations.Nullable;
1819

1920
import java.nio.ByteBuffer;
2021
import java.sql.SQLException;
@@ -37,7 +38,7 @@ public class JnaBlob extends AbstractFbBlob implements FbBlob, DatabaseListener
3738
private final IntByReference jnaHandle = new IntByReference(0);
3839
private final ISC_STATUS[] statusVector = new ISC_STATUS[JnaDatabase.STATUS_VECTOR_SIZE];
3940
private final FbClientLibrary clientLibrary;
40-
private ByteBuffer byteBuffer;
41+
private @Nullable ByteBuffer byteBuffer;
4142

4243
/**
4344
* Creates a blob for output (writing to the database).
@@ -85,10 +86,15 @@ public JnaDatabase getDatabase() {
8586
}
8687

8788
@Override
88-
public JnaTransaction getTransaction() {
89+
public @Nullable JnaTransaction getTransaction() {
8990
return (JnaTransaction) super.getTransaction();
9091
}
9192

93+
@Override
94+
protected final JnaTransaction requireActiveTransaction() throws SQLException {
95+
return (JnaTransaction) super.requireActiveTransaction();
96+
}
97+
9298
@Override
9399
public int getHandle() {
94100
return jnaHandle.getValue();
@@ -110,25 +116,20 @@ public void open() throws SQLException {
110116
throw FbExceptionBuilder.toNonTransientException(isc_segstr_no_op);
111117
}
112118

113-
final BlobParameterBuffer blobParameterBuffer = getBlobParameterBuffer();
114-
final byte[] bpb;
115-
if (blobParameterBuffer == null || blobParameterBuffer.isEmpty()) {
116-
bpb = ByteArrayHelper.emptyByteArray();
117-
} else {
118-
bpb = blobParameterBuffer.toBytesWithType();
119-
}
119+
byte[] bpb = getBlobParameterBuffer().toBytesWithType();
120120
try (var ignored = withLock()) {
121121
checkDatabaseAttached();
122122
checkTransactionActive();
123123
checkBlobClosed();
124124
clearDeferredException();
125125

126-
final JnaDatabase db = getDatabase();
126+
JnaDatabase db = getDatabase();
127+
JnaTransaction transaction = requireActiveTransaction();
127128
if (isOutput()) {
128-
clientLibrary.isc_create_blob2(statusVector, db.getJnaHandle(), getTransaction().getJnaHandle(),
129+
clientLibrary.isc_create_blob2(statusVector, db.getJnaHandle(), transaction.getJnaHandle(),
129130
getJnaHandle(), blobId, (short) bpb.length, bpb);
130131
} else {
131-
clientLibrary.isc_open_blob2(statusVector, db.getJnaHandle(), getTransaction().getJnaHandle(),
132+
clientLibrary.isc_open_blob2(statusVector, db.getJnaHandle(), transaction.getJnaHandle(),
132133
getJnaHandle(), blobId, (short) bpb.length, bpb);
133134
}
134135
processStatusVector();

jaybird-native/src/main/java/org/firebirdsql/gds/ng/jna/JnaConnection.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: Copyright 2014-2024 Mark Rotteveel
1+
// SPDX-FileCopyrightText: Copyright 2014-2026 Mark Rotteveel
22
// SPDX-License-Identifier: LGPL-2.1-or-later
33
package org.firebirdsql.gds.ng.jna;
44

@@ -8,6 +8,7 @@
88
import org.firebirdsql.gds.ng.*;
99
import org.firebirdsql.jna.fbclient.FbClientLibrary;
1010
import org.firebirdsql.jna.fbclient.ISC_STATUS;
11+
import org.jspecify.annotations.Nullable;
1112

1213
import java.nio.ByteOrder;
1314
import java.sql.SQLException;
@@ -130,7 +131,7 @@ private String getCString(ISC_STATUS lengthStatus, ISC_STATUS pointerStatus) {
130131
return getEncoding().decodeFromCharset(stringData);
131132
}
132133

133-
private String getString(ISC_STATUS iscStatus) {
134+
private @Nullable String getString(ISC_STATUS iscStatus) {
134135
long stringPointerAddress = iscStatus.longValue();
135136
if (stringPointerAddress == 0L) {
136137
System.getLogger(getClass().getName()).log(WARNING,

jaybird-native/src/main/java/org/firebirdsql/gds/ng/jna/JnaDatabase.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: Copyright 2014-2025 Mark Rotteveel
1+
// SPDX-FileCopyrightText: Copyright 2014-2026 Mark Rotteveel
22
// SPDX-FileCopyrightText: Copyright 2016 Adriano dos Santos Fernandes
33
// SPDX-License-Identifier: LGPL-2.1-or-later
44
package org.firebirdsql.gds.ng.jna;
@@ -13,6 +13,7 @@
1313
import org.firebirdsql.jna.fbclient.FbClientLibrary;
1414
import org.firebirdsql.jna.fbclient.ISC_STATUS;
1515
import org.firebirdsql.jna.fbclient.WinFbClientLibrary;
16+
import org.jspecify.annotations.Nullable;
1617

1718
import java.lang.ref.Cleaner;
1819
import java.nio.ByteBuffer;
@@ -274,7 +275,7 @@ public FbTransaction reconnectTransaction(long transactionId) throws SQLExceptio
274275
}
275276

276277
@Override
277-
public JnaStatement createStatement(FbTransaction transaction) throws SQLException {
278+
public JnaStatement createStatement(@Nullable FbTransaction transaction) throws SQLException {
278279
try {
279280
checkConnected();
280281
final JnaStatement stmt = new JnaStatement(this);
@@ -288,17 +289,18 @@ public JnaStatement createStatement(FbTransaction transaction) throws SQLExcepti
288289
}
289290

290291
@Override
291-
public FbBlob createBlobForOutput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer)
292+
public FbBlob createBlobForOutput(FbTransaction transaction, @Nullable BlobParameterBuffer blobParameterBuffer)
292293
throws SQLException {
293-
final JnaBlob jnaBlob = new JnaBlob(this, (JnaTransaction) transaction, blobParameterBuffer);
294+
var jnaBlob = new JnaBlob(this, (JnaTransaction) transaction, BlobParameterBuffer.orEmpty(blobParameterBuffer));
294295
jnaBlob.addExceptionListener(exceptionListenerDispatcher);
295296
return jnaBlob;
296297
}
297298

298299
@Override
299-
public FbBlob createBlobForInput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer, long blobId)
300-
throws SQLException {
301-
final JnaBlob jnaBlob = new JnaBlob(this, (JnaTransaction) transaction, blobParameterBuffer, blobId);
300+
public FbBlob createBlobForInput(FbTransaction transaction, @Nullable BlobParameterBuffer blobParameterBuffer,
301+
long blobId) throws SQLException {
302+
var jnaBlob = new JnaBlob(this, (JnaTransaction) transaction, BlobParameterBuffer.orEmpty(blobParameterBuffer),
303+
blobId);
302304
jnaBlob.addExceptionListener(exceptionListenerDispatcher);
303305
return jnaBlob;
304306
}
@@ -322,7 +324,7 @@ public byte[] getDatabaseInfo(final byte[] requestItems, final int maxBufferLeng
322324
}
323325

324326
@Override
325-
public void executeImmediate(String statementText, FbTransaction transaction) throws SQLException {
327+
public void executeImmediate(String statementText, @Nullable FbTransaction transaction) throws SQLException {
326328
// TODO also implement op_exec_immediate2
327329
try {
328330
if (isAttached()) {
@@ -390,6 +392,7 @@ protected JnaEventHandle validateEventHandle(EventHandle eventHandle) throws SQL
390392
}
391393

392394
@Override
395+
@SuppressWarnings("RedundantThrows")
393396
public JnaEventHandle createEventHandle(String eventName, EventHandler eventHandler) throws SQLException {
394397
final JnaEventHandle eventHandle = new JnaEventHandle(eventName, eventHandler, getEncoding());
395398
try (LockCloseable ignored = withLock()) {
@@ -472,7 +475,7 @@ private void processStatusVector() throws SQLException {
472475
processStatusVector(statusVector, getDatabaseWarningCallback());
473476
}
474477

475-
public void processStatusVector(ISC_STATUS[] statusVector, WarningMessageCallback warningMessageCallback)
478+
public void processStatusVector(ISC_STATUS[] statusVector, @Nullable WarningMessageCallback warningMessageCallback)
476479
throws SQLException {
477480
if (warningMessageCallback == null) {
478481
warningMessageCallback = getDatabaseWarningCallback();

jaybird-native/src/main/java/org/firebirdsql/gds/ng/jna/JnaEventHandle.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import org.firebirdsql.jaybird.util.Cleaners;
1414
import org.firebirdsql.jna.fbclient.FbClientLibrary;
1515
import org.firebirdsql.jna.fbclient.WinFbClientLibrary;
16-
import org.jspecify.annotations.NullMarked;
1716
import org.jspecify.annotations.Nullable;
1817

1918
/**
@@ -22,7 +21,6 @@
2221
* @author Mark Rotteveel
2322
* @since 3.0
2423
*/
25-
@NullMarked
2624
public final class JnaEventHandle extends AbstractEventHandle {
2725

2826
private static final System.Logger log = System.getLogger(JnaEventHandle.class.getName());

jaybird-native/src/main/java/org/firebirdsql/gds/ng/jna/JnaService.java

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: Copyright 2015-2025 Mark Rotteveel
1+
// SPDX-FileCopyrightText: Copyright 2015-2026 Mark Rotteveel
22
// SPDX-License-Identifier: LGPL-2.1-or-later
33
package org.firebirdsql.gds.ng.jna;
44

@@ -14,10 +14,12 @@
1414
import org.firebirdsql.gds.ng.LockCloseable;
1515
import org.firebirdsql.gds.ng.ParameterConverter;
1616
import org.firebirdsql.gds.ng.WarningMessageCallback;
17+
import org.firebirdsql.jaybird.util.ByteArrayHelper;
1718
import org.firebirdsql.jaybird.util.Cleaners;
1819
import org.firebirdsql.jdbc.FBDriverNotCapableException;
1920
import org.firebirdsql.jna.fbclient.FbClientLibrary;
2021
import org.firebirdsql.jna.fbclient.ISC_STATUS;
22+
import org.jspecify.annotations.Nullable;
2123

2224
import java.lang.ref.Cleaner;
2325
import java.nio.ByteBuffer;
@@ -77,20 +79,17 @@ protected boolean isConnected() {
7779
}
7880

7981
@Override
80-
public byte[] getServiceInfo(ServiceParameterBuffer serviceParameterBuffer,
82+
public byte[] getServiceInfo(@Nullable ServiceParameterBuffer serviceParameterBuffer,
8183
ServiceRequestBuffer serviceRequestBuffer, int maxBufferLength) throws SQLException {
8284
try {
83-
final byte[] serviceParameterBufferBytes = serviceParameterBuffer == null ? null
84-
: serviceParameterBuffer.toBytes();
85-
final byte[] serviceRequestBufferBytes =
86-
serviceRequestBuffer == null ? null : serviceRequestBuffer.toBytes();
87-
final ByteBuffer responseBuffer = ByteBuffer.allocateDirect(maxBufferLength);
85+
byte[] serviceParameterBufferBytes = serviceParameterBuffer != null ? serviceParameterBuffer.toBytes()
86+
: ByteArrayHelper.emptyByteArray();
87+
byte[] serviceRequestBufferBytes = serviceRequestBuffer.toBytes();
88+
var responseBuffer = ByteBuffer.allocateDirect(maxBufferLength);
8889
try (LockCloseable ignored = withLock()) {
8990
clientLibrary.isc_service_query(statusVector, handle, new IntByReference(0),
90-
(short) (serviceParameterBufferBytes != null ? serviceParameterBufferBytes.length
91-
: 0), serviceParameterBufferBytes,
92-
(short) (serviceRequestBufferBytes != null ? serviceRequestBufferBytes.length
93-
: 0), serviceRequestBufferBytes,
91+
(short) serviceParameterBufferBytes.length, serviceParameterBufferBytes,
92+
(short) serviceRequestBufferBytes.length, serviceRequestBufferBytes,
9493
(short) maxBufferLength, responseBuffer);
9594
processStatusVector();
9695
}
@@ -105,11 +104,10 @@ public byte[] getServiceInfo(ServiceParameterBuffer serviceParameterBuffer,
105104

106105
@Override
107106
public void startServiceAction(ServiceRequestBuffer serviceRequestBuffer) throws SQLException {
108-
byte[] serviceRequestBufferBytes = serviceRequestBuffer == null ? null : serviceRequestBuffer.toBytes();
107+
byte[] serviceRequestBufferBytes = serviceRequestBuffer.toBytes();
109108
try (LockCloseable ignored = withLock()) {
110109
clientLibrary.isc_service_start(statusVector, handle, new IntByReference(0),
111-
(short) (serviceRequestBufferBytes != null ? serviceRequestBufferBytes.length : 0),
112-
serviceRequestBufferBytes);
110+
(short) serviceRequestBufferBytes.length, serviceRequestBufferBytes);
113111
processStatusVector();
114112
} catch (SQLException e) {
115113
exceptionListenerDispatcher.errorOccurred(e);
@@ -193,6 +191,7 @@ public int getHandle() {
193191
return handle.getValue();
194192
}
195193

194+
@SuppressWarnings("unused")
196195
public IntByReference getJnaHandle() {
197196
return handle;
198197
}
@@ -213,12 +212,10 @@ private void processStatusVector() throws SQLException {
213212
processStatusVector(statusVector, getServiceWarningCallback());
214213
}
215214

216-
public void processStatusVector(ISC_STATUS[] statusVector, WarningMessageCallback warningMessageCallback)
215+
public void processStatusVector(ISC_STATUS[] statusVector, @Nullable WarningMessageCallback warningMessageCallback)
217216
throws SQLException {
218-
if (warningMessageCallback == null) {
219-
warningMessageCallback = getServiceWarningCallback();
220-
}
221-
connection.processStatusVector(statusVector, warningMessageCallback);
217+
connection.processStatusVector(statusVector,
218+
warningMessageCallback != null ? warningMessageCallback : getServiceWarningCallback());
222219
}
223220

224221
private record CleanupAction(IntByReference handle, FbClientLibrary library) implements Runnable {

0 commit comments

Comments
 (0)