Skip to content

Commit

Permalink
fix (jkube-kit/common) : PluginServiceFactory fails to resolve constr…
Browse files Browse the repository at this point in the history
…uctor arguments for more than one level subclasses

PluginServiceFactory tries to create ServiceImpl objects by invoking
their constructors with constructor parameter. This works fine when
constructor parameter is not using complex inheritance; but if we
provide a nested subtype as constructor argument to PluginServiceFactory (let's
say BaseA > BaseB > BaseC) it fails to resolve constructor argument.

Instead of just getting types via `constructorParameter.getClass().getInterfaces()` try getting all possible
subtypes recursively.

Signed-off-by: Rohan Kumar <rohaan@redhat.com>
  • Loading branch information
rohanKanojia authored and manusa committed Feb 16, 2023
1 parent 67aab45 commit 7777376
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -155,7 +154,7 @@ private <T> Constructor<T> findConstructor(Class<T> clazz) {
}
final List<Class<?>> types = new ArrayList<>();
types.add(constructorParameter.getClass());
types.addAll(Arrays.asList(constructorParameter.getClass().getInterfaces()));
types.addAll(getInterfacesForClass(constructorParameter.getClass()));
for (Class<?> type : types) {
try {
return clazz.getConstructor(type);
Expand All @@ -166,6 +165,15 @@ private <T> Constructor<T> findConstructor(Class<T> clazz) {
throw new IllegalStateException("Cannot load service " + clazz.getName());
}

private List<Class<?>> getInterfacesForClass(Class<?> clazz) {
List<Class<?>> interfacesList = new ArrayList<>();
for (Class<?> type : clazz.getInterfaces()) {
interfacesList.add(type);
interfacesList.addAll(getInterfacesForClass(type));
}
return interfacesList;
}

static class ServiceEntry implements Comparable<ServiceEntry> {

private final String className;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* Copyright (c) 2019 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at:
*
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.jkube.kit.common.util;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

class PluginServiceFactoryNestedContextTest {
private PluginServiceFactory<TestContext> pluginServiceFactory;

@BeforeEach
public void setup() {
pluginServiceFactory = new PluginServiceFactory<>(new DefaultTestContext());
}

@Test
void createServiceObjects_whenSubInterfacePassed_shouldMatchServiceImplementation() {
// Given
final String[] descriptorPaths = new String[] { "service/test-services-nested-context"};
// When
final List<TestService> result = pluginServiceFactory.createServiceObjects(descriptorPaths);
// Then
assertThat(result).hasSize(1);
}

public static class TestServiceImplWithBaseContext implements TestService {
public TestServiceImplWithBaseContext(BaseContext ctx) { }

@Override
public String getName() { return "one"; }
}

private interface TestService {
String getName();
}

private static class DefaultTestContext implements TestContext { }

private interface TestContext extends BaseContext { }

private interface BaseContext { }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.eclipse.jkube.kit.common.util.PluginServiceFactoryNestedContextTest$TestServiceImplWithBaseContext,5

0 comments on commit 7777376

Please sign in to comment.