Troubleshooting¶
This guide covers common runtime, Spring Boot starter, and code generation failures.
The project is Python-first. JavaScript support exists as an experimental runtime path only, and JavaScript code generation is not supported in the current release line.
Script Not Found¶
Symptom:
- runtime binding fails with
ScriptNotFoundException - Spring Boot fail-fast startup fails before the application starts
- preload fails for a configured script name
Likely cause:
- the script file is not in the location expected by the configured
ScriptSource - the Java interface name does not match the default snake-case script name
- Spring Boot
polyglot.python.resources-pathorpolyglot.js.resources-pathpoints to the wrong location
Fix:
- For
ForecastService, useforecast_service.pyfor Python. - Check that the configured resource path contains the script.
- For Spring Boot, use logical preload names without the
.pysuffix.
Minimal Python script:
import polyglot
class ForecastService:
def forecast(self, city):
return {"city": city, "temperature": 21}
polyglot.export_value("ForecastService", ForecastService)
Minimal Java binding:
FileSystemScriptSource scripts = new FileSystemScriptSource(Path.of("src/main"));
try (PyExecutor executor = PyExecutor.create(scripts, null)) {
ForecastService service = executor.bind(ForecastService.class);
service.forecast("Kyiv");
}
With FileSystemScriptSource(Path.of("src/main")), the script should be located at
src/main/python/forecast_service.py.
Export Not Found¶
Symptom:
- binding fails with a message like
Python class 'ForecastService' not found validateBinding(...)fails even though the script file exists
Likely cause:
- the Python script did not call
polyglot.export_value(...) - the exported value name does not match the Java interface simple name
- the script raised an error before exporting the value
Fix:
- Export the contract under the Java interface simple name.
- Keep the adapter-facing export small and explicit.
Python class-style export:
import polyglot
class ForecastService:
def forecast(self, city):
return {"city": city}
polyglot.export_value("ForecastService", ForecastService)
Python dictionary-style export:
import polyglot
def forecast(city):
return {"city": city}
polyglot.export_value("ForecastService", {"forecast": forecast})
Method Not Executable¶
Symptom:
validateBinding(...)reports that a Python method is not found or not executable- the proxy is created, but a method call fails at runtime
Likely cause:
- the Java interface method name does not exist on the exported Python object
- a dictionary-style export is missing the method key
- the exported member exists but is not callable
Fix:
- Match Java method names exactly.
- For dictionary-style exports, map every Java method name to a Python function.
Java contract:
public interface StatsApi {
Double mean(List<Double> values);
}
Python implementation:
import polyglot
class StatsApi:
def mean(self, values):
return sum(values) / len(values)
polyglot.export_value("StatsApi", StatsApi)
Wrong Convention¶
Symptom:
- Python binding fails even though the function exists
- JavaScript binding fails when using
Convention.BY_INTERFACE_EXPORT - Spring Boot client creation fails for a client with an unsupported convention
Likely cause:
Convention.DEFAULTandConvention.BY_INTERFACE_EXPORTexpect a Python export named after the Java interfaceConvention.BY_METHOD_NAMEexpects functions to be available directly in language bindings- JavaScript supports only the method-name style in the current experimental runtime path
Fix:
- For Python class or dictionary exports, use
DEFAULTorBY_INTERFACE_EXPORT. - For direct top-level Python functions, use
BY_METHOD_NAME. - Do not use
BY_INTERFACE_EXPORTfor JavaScript.
Python BY_METHOD_NAME example:
def forecast(city):
return {"city": city}
Java:
ForecastService service = executor.bind(ForecastService.class, Convention.BY_METHOD_NAME);
Missing GraalVM Language Dependency¶
Symptom:
- GraalVM reports that a language is not installed or cannot be initialized
- Python or JavaScript works locally but fails in CI or another application
- Spring Boot creates no executor for an enabled language
Likely cause:
- the application added
polyglot-adapterbut not the language runtime dependency - the dependency versions are not aligned with the runtime BOM
- CI is not running on the verified GraalVM line
Fix:
- Import
polyglot-bom. - Add only the GraalVM language dependencies you use.
- Use GraalVM JDK 25.x for the currently verified runtime line.
Python dependencies:
<dependency>
<groupId>org.graalvm.python</groupId>
<artifactId>python-embedding</artifactId>
</dependency>
<dependency>
<groupId>org.graalvm.python</groupId>
<artifactId>python-launcher</artifactId>
</dependency>
Experimental JavaScript runtime dependency:
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js</artifactId>
<type>pom</type>
</dependency>
Spring Boot Bean And Client Resolution Issues¶
Symptom:
- no Spring bean is created for an interface annotated with
@PolyglotClient - startup fails because multiple executors are available
- startup fails because no executor is available for the requested language
Likely cause:
@EnablePolyglotClientsscans the wrong package- the client does not specify a language while both Python and JavaScript executors are available
- the requested language is not enabled under
polyglot.* - required language dependencies are missing
Fix:
- Put
@EnablePolyglotClientson a configuration class in the parent package, or setbasePackages. - Prefer explicit language selection for public application clients.
- Enable the matching language configuration.
Spring Boot example:
@SpringBootApplication
@EnablePolyglotClients(basePackages = "com.example.contracts")
class DemoApplication {}
@PolyglotClient(languages = {SupportedLanguage.PYTHON})
public interface ForecastService {
Map<String, Object> forecast(String city);
}
polyglot:
python:
enabled: true
resources-path: classpath:python
Preload And Fail-Fast Startup Failures¶
Symptom:
- Spring Boot fails during startup when
polyglot.core.fail-fast=true - preload fails before any client method is called
- a script appears to run twice: once during preload and once during binding
Likely cause:
- fail-fast eagerly validates
@PolyglotClientbindings - preload evaluates named scripts as raw script evaluation
- preload does not bind Java interfaces and does not populate interface caches
- script side effects can happen again when the contract is later bound
Fix:
- Treat preload as startup visibility/warmup, not contract prebinding.
- Keep preload scripts idempotent.
- Use
validateBinding(...)or Spring fail-fast for contract validation. - Use logical script names in
preload-scripts.
Spring Boot example:
polyglot:
core:
fail-fast: true
python:
enabled: true
resources-path: classpath:python
warmup-on-startup: true
preload-scripts:
- bootstrap
This expects python/bootstrap.py.
Codegen Parser Limitations¶
Symptom:
polyglot:generate,polyglot:check, orpolyglot:doctorfails while parsing Python- generated Java uses
Objectwhere a more precise type was expected - no Java interfaces are generated
Likely cause:
- the Python parser supports a documented adapter-oriented subset, not full Python semantic analysis
- the script does not use
polyglot.export_value(...) - type hints are missing or outside the supported type model
- JavaScript code generation is not implemented
Fix:
- Keep generated contracts simple and explicit.
- Use
polyglot.export_value(...). - Use
strictMode=truefor contracts intended to become stable Java-facing APIs. - Do not expect JavaScript code generation in the current release line.
Python codegen-friendly example:
import polyglot
class ForecastService:
def forecast(self, city: str) -> dict:
return {"city": city}
polyglot.export_value("ForecastService", ForecastService)
Codegen Drift And Check Failures¶
Symptom:
polyglot:checkfails with generated file drift- CI fails but local generation appears to work
- generated sources differ from committed generated files
Likely cause:
- Python contracts changed but generated Java sources were not refreshed
- codegen configuration differs between local and CI
- generated files were edited manually
Fix:
- Run
polyglot:generatelocally and commit the generated source changes. - Use the same plugin configuration in local and CI builds.
- Treat generated Java as output from Python contracts, not hand-maintained source.
Common workflow:
mvn -B -ntp polyglot:generate
mvn -B -ntp polyglot:check
JavaScript Support Limitations¶
Symptom:
- JavaScript binding works only for direct function-style contracts
BY_INTERFACE_EXPORTfails for JavaScript- JavaScript code generation throws
UnsupportedOperationException
Likely cause:
- JavaScript is an experimental runtime-only path
- the current JavaScript runtime expects functions in JavaScript bindings by Java method name
- JavaScript contract generation is not implemented
Fix:
- Keep JavaScript usage narrow and runtime-only.
- Use
Convention.DEFAULTorConvention.BY_METHOD_NAMEfor JavaScript. - Do not use JavaScript as a parity path with Python before the project explicitly promotes it.
Experimental JavaScript example:
function forecast(city) {
return { city: city, temperature: 21 };
}
Java:
ForecastService service = jsExecutor.bind(ForecastService.class, Convention.BY_METHOD_NAME);
Trusted Scripts And allowAllAccess¶
Symptom:
- security review asks whether guest scripts are sandboxed
- an application wants to execute user-supplied Python or JavaScript
Likely cause:
- contexts created by the adapter use GraalVM host access settings intended for trusted application-owned scripts
- this project is not a sandboxing framework
Fix:
- Execute only trusted scripts packaged with or controlled by the application.
- Do not pass user-supplied code to the adapter.
- If untrusted execution is required, design and verify a separate sandboxing boundary outside this library.
Security rule:
Application-owned scripts: supported use case.
Untrusted user-supplied scripts: not a supported use case.