FLX-1002¶
Exported service method 'com.example.PriceQuery.lastPrice' returns java.lang.String, which cannot be generated
| Severity | ERROR |
| Category | ANNOTATION |
| Element | NODE |
The rule¶
An @ExportService method must return void, or boolean to control propagation.
Why the compiler says this¶
The generated processor implements the exported interface, and Fluxtion renders every exported method as a void dispatch that calls the node and returns. There is nowhere for a value to come back through, so a method declaring one produces an override that does not match the interface and the generated source fails to compile. Reported here, before generation, so the failure names your interface rather than a line inside generated code. boolean is exempt: it compiles and controls whether the call marks the node dirty.
How to fix it¶
Change com.example.PriceQuery.lastPrice to return void — an exported method is a command, and its value is discarded either way. If it is a QUERY, do not export it: read the node with flow.getNodeById("priceNode") and call the method on the node directly. If the return value was controlling propagation, declare it boolean.
Example¶
Both examples are compiled and put through a real Fluxtion.compile on every build, so the first is guaranteed to produce this diagnostic and the second to build cleanly. Note that the failing example is valid Java — javac is happy, and Fluxtion refuses it for its own reasons.
The code that causes it¶
package com.telamin.fluxtion.builder.diagnostic.examples;
import com.telamin.fluxtion.builder.generation.config.EventProcessorConfig;
import com.telamin.fluxtion.runtime.annotations.ExportService;
/** FLX-1002 — an exported method that returns a value. */
public class Flx1002Failing {
public interface PriceQuery {
// A QUERY. The generated processor implements this interface, and Fluxtion renders every
// exported method as a void dispatch — there is nowhere for a value to come back through.
String lastPrice();
}
public static class PriceNode implements @ExportService PriceQuery {
private String price = "unset";
@Override
public String lastPrice() {
return price;
}
}
public static void graph(EventProcessorConfig config) {
config.addNode(new PriceNode(), "priceNode");
}
}
The code that fixes it¶
package com.telamin.fluxtion.builder.diagnostic.examples;
import com.telamin.fluxtion.builder.generation.config.EventProcessorConfig;
import com.telamin.fluxtion.runtime.annotations.ExportService;
/** FLX-1002 fixed — commands are exported; the query reads the node directly. */
public class Flx1002Fixed {
public interface PriceCommands {
// void: a command surface, which is what @ExportService is for.
void reset();
// boolean is also accepted: it controls whether the call marks the node dirty.
boolean applyTick(int tick);
}
public static class PriceNode implements @ExportService PriceCommands {
private String price = "unset";
@Override
public void reset() {
price = "unset";
}
@Override
public boolean applyTick(int tick) {
price = String.valueOf(tick);
return true;
}
// Not exported. To READ the node, look it up:
// PriceNode node = flow.getNodeById("priceNode");
// String price = node.lastPrice();
public String lastPrice() {
return price;
}
}
public static void graph(EventProcessorConfig config) {
config.addNode(new PriceNode(), "priceNode");
}
}
Which builds raise it¶
Source-generating (AOT) builds only, and raised BEFORE generation so the failure names your interface instead of a line inside generated code.
Reading it programmatically¶
This diagnostic is also written to the machine-readable report — the opt-in sidecar (-Dfluxtion.diagnostics.sidecar=true), or FluxtionDiagnostics.capture(...) for a caller that wants the objects:
{
"code": "FLX-1002",
"severity": "ERROR",
"category": "ANNOTATION",
"element": { "kind": "NODE", … }
}
Select findings by severity, never by position: a failing build's report also contains any warnings it found, and diagnostics[0] is not the cause of the failure.
This page is generated from the compiler itself, so the wording above is exactly what a build emits. Do not edit it by hand — it is overwritten whenever the diagnostics are regenerated.