spring-projects/spring-framework · error · IllegalArgumentException

Invalid method signature '${signature}': expected closing ')

Error message

Invalid method signature '${signature}': expected closing ')' for args list

What it means

Thrown as IllegalArgumentException by resolveSignature when the supplied signature string contains an opening '(' but no matching closing ')', making the argument list malformed (BeanUtils.java:457-460). Parsing stops before any method lookup.

Source

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

	 * argument type list, only the method whose name and argument types match will be returned.
	 * <p>Note then that {@code methodName} and {@code methodName()} are <strong>not</strong>
	 * resolved in the same way. The signature {@code methodName} means the method called
	 * {@code methodName} with the least number of arguments, whereas {@code methodName()}
	 * 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());

View on GitHub (pinned to e8729d0438)

Solutions

  1. Supply a well-formed signature with a closing ')', e.g. 'foo(int, java.lang.String)'.
  2. If you want the minimal-arg method, omit parentheses entirely: 'foo' (see resolveSignature docs).
  3. Validate the signature string at config load time (must contain '(' only together with a later ')').
  4. Add a unit test that parses the configured signature against a known class.

Example fix

// before
resolveSignature("doWork(String", clazz); // missing ')'

// after
resolveSignature("doWork(String)", clazz);
Defensive patterns

Strategy: validation

Validate before calling

int open = signature.indexOf('('), close = signature.indexOf(')');
if (open > -1 && close == -1) {
  throw new IllegalArgumentException("Malformed signature, missing ')': " + signature);
}

Type guard

public static boolean isBalancedSignature(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 e) { /* fix the signature string */ }

Prevention

When it happens

Trigger: resolveSignature('foo(int', clazz) or any signature like 'doWork(String' where the closing parenthesis is missing or mistyped.

Common situations: Externalizing method names in properties/YAML and truncating the value; string concatenation that drops the ')'; copy-paste errors in config; whitespace/encoding corruption of the signature.

Related errors


AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04). Data as JSON: /data/errors/e445e328b7f0a1e7.json. Report an issue: GitHub.