spring-projects/spring-framework · warning · IllegalArgumentException

Invalid method signature '{signature}': expected opening '('

Error message

Invalid method signature '{signature}': expected opening '(' for args list

What it means

Thrown as IllegalArgumentException by resolveSignature at BeanUtils.java:462 when the signature string contains a closing ')' but no opening '('. The parser pairs '(' and ')'; a ')' with no '(' is structurally invalid and rejected with a precise hint.

Source

Thrown at spring-beans/src/main/java/org/springframework/beans/BeanUtils.java:462

	 * means the method called {@code methodName} with exactly 0 arguments.
	 * <p>If no method can be found, then {@code null} is returned.
	 * @param signature the method signature as String representation
	 * @param clazz the class to resolve the method signature against
	 * @return the resolved Method
	 * @see #findMethod
	 * @see #findMethodWithMinimalParameters
	 */
	public static @Nullable Method resolveSignature(String signature, Class<?> clazz) {
		Assert.hasText(signature, "'signature' must not be empty");
		Assert.notNull(clazz, "Class must not be null");
		int startParen = signature.indexOf('(');
		int endParen = signature.indexOf(')');
		if (startParen > -1 && endParen == -1) {
			throw new IllegalArgumentException("Invalid method signature '" + signature +
					"': expected closing ')' for args list");
		}
		else if (startParen == -1 && endParen > -1) {
			throw new IllegalArgumentException("Invalid method signature '" + signature +
					"': expected opening '(' for args list");
		}
		else if (startParen == -1) {
			return findMethodWithMinimalParameters(clazz, signature);
		}
		else {
			String methodName = signature.substring(0, startParen);
			String[] parameterTypeNames =
					StringUtils.commaDelimitedListToStringArray(signature.substring(startParen + 1, endParen));
			Class<?>[] parameterTypes = new Class<?>[parameterTypeNames.length];
			for (int i = 0; i < parameterTypeNames.length; i++) {
				String parameterTypeName = parameterTypeNames[i].trim();
				try {
					parameterTypes[i] = ClassUtils.forName(parameterTypeName, clazz.getClassLoader());
				}
				catch (Throwable ex) {
					throw new IllegalArgumentException("Invalid method signature: unable to resolve type [" +
							parameterTypeName + "] for argument " + i + ". Root cause: " + ex);

View on GitHub (pinned to 69bf83ad71)

Solutions

  1. Add the matching opening '(' so the signature is well-formed, e.g. "doStuff()".
  2. If you intended name-only lookup, drop the ')' entirely: "doStuff".
  3. Sanity-check the signature: it must have both '(' and ')' or neither.

Example fix

// before
Method m = BeanUtils.resolveSignature("doStuff)", clazz);

// after
Method m = BeanUtils.resolveSignature("doStuff()", clazz);
Defensive patterns

Strategy: validation

Validate before calling

int open = signature.indexOf('('), close = signature.indexOf(')');
boolean ok = (open == -1 && close == -1) || (open > -1 && close > open);
if (ok) BeanUtils.resolveSignature(signature, clazz);

Type guard

static boolean wellFormedSignature(String s) {
    int o = s.indexOf('('), c = s.indexOf(')');
    return (o == -1 && c == -1) || (o > -1 && c > o);
}

Try / catch

try {
    BeanUtils.resolveSignature(sig, clazz);
} catch (IllegalArgumentException ex) {
    if (ex.getMessage().contains("opening '('")) {
        sig = sig.replace(")", "()"); // or fix the source
    } else throw ex;
}

Prevention

When it happens

Trigger: Calling BeanUtils.resolveSignature("doStuff)", clazz) or any signature with a stray ')' and no '('. Typical when a signature is malformed by string slicing or a typo in configuration.

Common situations: Mis-edited XML/annotation method expressions; generated code that injects a suffix ')'; YAML/properties value corruption; user-typed method signatures in admin tooling.

Related errors


AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09). Data as JSON: /api/errors/848f45419665ef0c. Report an issue: GitHub.