apache/skywalking · error · IllegalArgumentException
pool must not be null
Error message
pool must not be null
What it means
The pool-aware MeterSystem.create(String, String, ScopeType, Class, ClassPool, Class) overload is used by the runtime MAL/LAL rule applier, which builds a fresh ClassPool and a per-file RuleClassLoader for each rule file. It rejects a null pool up front because every subsequent step (resolving the function CtClass, generating and toClass()-ing the Metrics subclass) dereferences it. This is a fail-fast guard against internal API misuse, not a user-config error.
Source
Thrown at oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/MeterSystem.java:365
* @param functionName function provided through {@link MeterFunction}
* @param type scope type
* @param dataType accepted value data type
* @param pool per-file Javassist pool, typically constructed as
* {@code new ClassPool(ClassPool.getDefault())} with
* {@code LoaderClassPath(ruleLoader)} appended
* @param classLoaderNeighbor a class loaded by the per-file {@code RuleClassLoader}; used
* by Javassist's {@code toClass(Class)} on Java 9+ to resolve
* the target loader. On Java 8, its classloader is passed to
* the legacy {@code toClass(ClassLoader, ProtectionDomain)}
*/
public synchronized <T> void create(String metricsName,
String functionName,
ScopeType type,
Class<T> dataType,
ClassPool pool,
Class<?> classLoaderNeighbor) throws IllegalArgumentException {
if (pool == null) {
throw new IllegalArgumentException("pool must not be null");
}
if (classLoaderNeighbor == null) {
throw new IllegalArgumentException("classLoaderNeighbor must not be null");
}
createInternal(metricsName, functionName, type, dataType, pool, classLoaderNeighbor,
StorageManipulationOpt.withSchemaChange());
}
/**
* Remove a previously-registered metric by name. Symmetric to {@link #create(String, String,
* ScopeType, Class)} / the pool-aware overload. Used by runtime rule hot-remove (MAL/LAL)
* to retire a metric class cleanly.
*
* <p>Steps:
* <ol>
* <li>Drops the {@link #meterPrototypes} entry so {@link #buildMetrics(String, Class)}
* rejects further builds for this name.</li>
* <li>Delegates to {@link MetricsStreamProcessor#removeMetric} — L1/L2 drain, workerView on GitHub (pinned to 102af09b4a)
Solutions
- Construct and pass a real pool: ClassPool pool = ClassPool.getDefault(); pool.appendClassPath(...) for the rule's loader — see the runtime applier in oap-server/analyzer for the canonical pattern
- If you do not need a custom loader, call the simpler overload create(metricsName, functionName, type, dataType) which uses the default pool
Example fix
// before meterSystem.create(name, func, type, Long.class, null, neighbor); // after ClassPool pool = ClassPool.getDefault(); pool.appendClassPath(new ClassClassPath(functionClass)); meterSystem.create(name, func, type, Long.class, pool, neighbor);
Defensive patterns
Strategy: validation
Validate before calling
ClassPool pool = (pool == null) ? ClassPool.getDefault() : pool; // or simply reject before calling: // Objects.requireNonNull(pool, "pool"); meterSystem.create(name, func, type, dataType, pool, neighbor);
Prevention
- Default to ClassPool.getDefault() when no isolation is needed
- In tests, build the pool in @BeforeEach so it can never be null at the call site
- Reserve the pool-aware overload for callers that actually manage a rule ClassLoader
When it happens
Trigger: Calling the pool-aware create overload with a null ClassPool — typically a custom embedding of MeterSystem, a unit test stubbing the rule applier, or a code path that builds a pool lazily and passes the unassigned field.
Common situations: Third-party code embedding the OAP core MeterSystem outside the standard server-starter; test harnesses that pass null intending the default-pool overload to be selected, but matching the pool overload because of an extra argument; refactors that removed pool construction from a branch.
Related errors
- classLoaderNeighbor must not be null
- Function {} doesn't inherit from Metrics.
- Function {} can't be found by javaassist.
- MeterSystem unavailable for MAL compile of {sourceName}
- {} has been defined, but calculate function or/are scope typ
AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14).
Data as JSON: /api/errors/c7427b3e5a58f2a2.
Report an issue: GitHub.