mardi 20 août 2019

Could not invoke method: java.lang.IllegalArgumentException: argument type mismatch

I am trying to invoke a method through reflection on an EJB that has been looked up through its JNDI reference. It requires three arguments: a EndUser object (custom object), a Set (custom class) and a boolean. The first object causes the invocation to fail with a "Could not invoke method: java.lang.IllegalArgumentException: argument type mismatch". This occurs as long as the first argument is non-null. Setting it to null makes the error go away.

The actual call:

  public Relation createRelation(final Relation relation, final HashSet<Contact> contacts) {
        final EndUser user = new EndUser();
        Object[] args = new Object[]{user, contacts, false};

        try {
            return (Relation) EjbUtils.invoke("registerEndUser", REGISTRATION_SERVICE_JNDI, args);
        } catch (final Throwable throwable) {
            LOGGER.error("Could not invoke method", throwable);

            return null;
        }
}

The EjbUtils method:

 public static Object invoke(final String methodName, final String ejbName, final Object... args) throws Throwable {
        final String jndiName = getEjbJndi(ejbName);
        final Object remoteObject = lookup(jndiName);
        final Method[] methods = remoteObject.getClass().getMethods();

        for (final Method method : methods) {
            if (methodName.equals(method.getName()) && args.length == method.getParameterCount()) {
                try {
                    return method.invoke(remoteObject, args);
                } catch (IllegalAccessException e) {
                    final String message = String.format("Could not invoke method %s on %s: %s", methodName, ejbName, e.getMessage());
                    LOGGER.error(message);
                    throw new IllegalStateException(message, e);
                } catch (InvocationTargetException e) {
                    throw e.getCause();
                }
            }
        }

        throw new IllegalArgumentException("Method not found");
    }

The method I am trying to invoke:

    public Relation registerEndUser(final EndUser relation, final Set<Contact> contacts, boolean sendMail)
            throws RegistrationServiceException, RegistrationServiceWarning {
        return registerRelation(relation, contacts, sendMail);
    }

The weird part is: if I replace

final EndUser user = new EndUser();

with

final EndUser user = null;

No exception is thrown and the method is invoked, which should indicate the arguments are of the correct type.

When debugging I can see the correct method is found, and the required parameter types are identical to the ones I provide.





Aucun commentaire:

Enregistrer un commentaire