Skip to content

Commit 07cabfb

Browse files
committed
spotbugs(WEM+UVA) Batches 4+5: leaf-class enrichments + array→varargs (10 cleared)
Batch 4 — leaf-class WEM (5 sites): - ChatMessage.requireNonEmpty: message now distinguishes null vs size=0 input - ChatRequest.setMaxToolRounds: message now includes the rejected value - ContentPart.imageBytes: message now includes bytes.length so the operator knows which call failed - LlamaLoader.getNativeResourcePath: message now includes the active classLoader so the operator can debug class-loading issues - LlamaPublisher.subscribe: message now references reactive-streams §1.9 and includes the calling thread name (the spec rule citation helps callers, the thread name is the WEM runtime expression) Batch 5 — UVA array → varargs (5 sites): - InferenceParameters.setPenaltyPrompt(int[]) -> int... - LlamaModel.decode(int[]) -> int... - LlamaModel.decodeBytes(int[]) -> int... (native) - LlamaModel.handleDetokenize(int[]) -> int... (native) - ParameterJsonSerializer.buildIntArray(int[]) -> int... Varargs is source-compatible with all existing array call sites; the new call shape f(1, 2, 3) is additionally allowed. Bytecode signature stays [I with the ACC_VARARGS bit flipped on — JNI doesn't enforce the bit, so native method signatures are unchanged on the C side. Test impact (LlamaPublisherTest.nullSubscriberThrows): - Previously: assertEquals("subscriber", ...) — exact-match assertion. - Now: assertTrue(msg.startsWith("reactive-streams §1.9: subscriber must not be null"), ...) — prefix-match so the runtime thread-name suffix doesn't break the assertion across environments. Test slice green: 162 tests across ChatMessageTest (2), ChatRequestTest, ContentPartTest (14), LlamaLoaderTest (21), LlamaPublisherTest (4), InferenceParametersTest (86), ParameterJsonSerializerTest (35). SpotBugs Max+Low: WEM goes 5 -> 0, UVA goes 5 -> 0. Total jllama: 34 -> 25.
1 parent 311f8d6 commit 07cabfb

9 files changed

Lines changed: 20 additions & 11 deletions

File tree

src/main/java/net/ladenthin/llama/ChatMessage.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,9 @@ private ChatMessage(
9898

9999
private static List<ContentPart> requireNonEmpty(List<ContentPart> parts) {
100100
if (parts == null || parts.isEmpty()) {
101-
throw new IllegalArgumentException("parts must not be null or empty");
101+
throw new IllegalArgumentException(
102+
"parts must not be null or empty (was "
103+
+ (parts == null ? "null" : "size=0") + ")");
102104
}
103105
return parts;
104106
}

src/main/java/net/ladenthin/llama/ChatRequest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public ChatRequest setToolChoice(@Nullable String toolChoice) {
105105
*/
106106
public ChatRequest setMaxToolRounds(int maxToolRounds) {
107107
if (maxToolRounds <= 0) {
108-
throw new IllegalArgumentException("maxToolRounds must be > 0");
108+
throw new IllegalArgumentException("maxToolRounds must be > 0 but was " + maxToolRounds);
109109
}
110110
this.maxToolRounds = maxToolRounds;
111111
return this;

src/main/java/net/ladenthin/llama/ContentPart.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ public static ContentPart imageBytes(byte[] bytes, String mimeType) {
9292
Objects.requireNonNull(bytes, "bytes");
9393
Objects.requireNonNull(mimeType, "mimeType");
9494
if (mimeType.isEmpty()) {
95-
throw new IllegalArgumentException("mimeType must not be empty");
95+
throw new IllegalArgumentException(
96+
"mimeType must not be empty (bytes.length=" + bytes.length + ")");
9697
}
9798
String encoded = Base64.getEncoder().encodeToString(bytes);
9899
return new ContentPart(Type.IMAGE_URL, null, "data:" + mimeType + ";base64," + encoded);

src/main/java/net/ladenthin/llama/InferenceParameters.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ public InferenceParameters setPenaltyPrompt(String penaltyPrompt) {
388388
* @param tokens the token ids of the prompt portion to penalize for repetition
389389
* @return this builder
390390
*/
391-
public InferenceParameters setPenaltyPrompt(int[] tokens) {
391+
public InferenceParameters setPenaltyPrompt(int... tokens) {
392392
if (tokens.length > 0) {
393393
parameters.put(
394394
PARAM_PENALTY_PROMPT, serializer.buildIntArray(tokens).toString());

src/main/java/net/ladenthin/llama/LlamaLoader.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,9 @@ static String getNativeResourcePath() {
267267
final Package pkg = LlamaLoader.class.getPackage();
268268
// LlamaLoader is in a named package, so Class.getPackage() is never null here.
269269
if (pkg == null) {
270-
throw new IllegalStateException("LlamaLoader.class.getPackage() returned null");
270+
throw new IllegalStateException(
271+
"LlamaLoader.class.getPackage() returned null (classLoader="
272+
+ LlamaLoader.class.getClassLoader() + ")");
271273
}
272274
String packagePath = pkg.getName().replace('.', '/');
273275
return String.format("/%s/%s", packagePath, OSInfo.getNativeLibFolderPathForCurrentOS());

src/main/java/net/ladenthin/llama/LlamaModel.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ public LlamaIterable generate(InferenceParameters parameters) {
376376
* @param tokens an array of tokens
377377
* @return the token ids decoded to a string
378378
*/
379-
public String decode(int[] tokens) {
379+
public String decode(int... tokens) {
380380
byte[] bytes = decodeBytes(tokens);
381381
return new String(bytes, StandardCharsets.UTF_8);
382382
}
@@ -426,7 +426,7 @@ protected final void finalize() {
426426

427427
native void cancelCompletion(int taskId);
428428

429-
native byte[] decodeBytes(int[] tokens);
429+
native byte[] decodeBytes(int... tokens);
430430

431431
private native void loadModel(String... parameters);
432432

@@ -700,7 +700,7 @@ public LlamaIterable generateChat(InferenceParameters parameters) {
700700
* @param tokens array of token IDs
701701
* @return JSON response with the decoded text
702702
*/
703-
public native String handleDetokenize(int[] tokens);
703+
public native String handleDetokenize(int... tokens);
704704

705705
// ------------------------------------------------------------------
706706
// Server management

src/main/java/net/ladenthin/llama/LlamaPublisher.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ public final class LlamaPublisher implements Publisher<LlamaOutput> {
5959
@Override
6060
public void subscribe(Subscriber<? super LlamaOutput> subscriber) {
6161
if (subscriber == null) {
62-
throw new NullPointerException("subscriber");
62+
throw new NullPointerException(
63+
"reactive-streams §1.9: subscriber must not be null (caller thread="
64+
+ Thread.currentThread().getName() + ")");
6365
}
6466
if (!subscribed.compareAndSet(false, true)) {
6567
EmptySubscription.signalError(

src/main/java/net/ladenthin/llama/json/ParameterJsonSerializer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ public ArrayNode buildSamplers(Sampler... samplers) {
183183
* @param values the token IDs to include
184184
* @return a Jackson {@link ArrayNode} of integer values
185185
*/
186-
public ArrayNode buildIntArray(int[] values) {
186+
public ArrayNode buildIntArray(int... values) {
187187
ArrayNode arr = OBJECT_MAPPER.createArrayNode();
188188
for (int v : values) arr.add(v);
189189
return arr;

src/test/java/net/ladenthin/llama/LlamaPublisherTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,9 @@ public void nullSubscriberThrows() {
196196
new LlamaPublisher(null, null, false).subscribe(null);
197197
fail("expected NPE");
198198
} catch (NullPointerException expected) {
199-
assertEquals("subscriber", expected.getMessage());
199+
assertTrue(
200+
expected.getMessage().startsWith("reactive-streams §1.9: subscriber must not be null"),
201+
"actual: " + expected.getMessage());
200202
}
201203
}
202204
}

0 commit comments

Comments
 (0)