Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rest-http-interface example code can't run #34443

Closed
Fabriceli opened this issue Feb 18, 2025 · 3 comments
Closed

rest-http-interface example code can't run #34443

Fabriceli opened this issue Feb 18, 2025 · 3 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: documentation A documentation task
Milestone

Comments

@Fabriceli
Copy link

Base info:

  • JAVA version: 17
  • Spring boot version: 3.2.6

Reproduce steps:

  1. copy this code from rest-http-interface
interface RepositoryService {

	@GetExchange("/repos/{owner}/{repo}")
	Repository getRepository(@PathVariable String owner, @PathVariable String repo);

	// more HTTP exchange methods...

}
  1. run the project got error:
2025-02-18T16:08:00.290+08:00 ERROR 41328 --- [nio-8088-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.IllegalArgumentException: non-public interface is not defined by the given loader] with root cause

java.lang.IllegalArgumentException: non-public interface is not defined by the given loader
	at java.base/java.lang.reflect.Proxy$ProxyBuilder.mapToModule(Proxy.java:818) ~[na:na]
	at java.base/java.lang.reflect.Proxy$ProxyBuilder.<init>(Proxy.java:651) ~[na:na]
	at java.base/java.lang.reflect.Proxy.lambda$getProxyConstructor$1(Proxy.java:440) ~[na:na]
	at java.base/jdk.internal.loader.AbstractClassLoaderValue$Memoizer.get(AbstractClassLoaderValue.java:329) ~[na:na]
	at java.base/jdk.internal.loader.AbstractClassLoaderValue.computeIfAbsent(AbstractClassLoaderValue.java:205) ~[na:na]
	at java.base/java.lang.reflect.Proxy.getProxyConstructor(Proxy.java:438) ~[na:na]
	at java.base/java.lang.reflect.Proxy.newProxyInstance(Proxy.java:1037) ~[na:na]
	at org.springframework.aop.framework.JdkDynamicAopProxy.getProxy(JdkDynamicAopProxy.java:124) ~[spring-aop-6.1.8.jar:6.1.8]
	at org.springframework.aop.framework.JdkDynamicAopProxy.getProxy(JdkDynamicAopProxy.java:116) ~[spring-aop-6.1.8.jar:6.1.8]
	at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:97) ~[spring-aop-6.1.8.jar:6.1.8]
	at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:137) ~[spring-aop-6.1.8.jar:6.1.8]
	at org.springframework.web.service.invoker.HttpServiceProxyFactory.createClient(HttpServiceProxyFactory.java:91) ~[spring-web-6.1.8.jar:6.1.8]
	at com.igwfmc.DemoController.proxy(DemoController.java:32) ~[main/:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255) ~[spring-web-6.1.8.jar:6.1.8]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188) ~[spring-web-6.1.8.jar:6.1.8]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.1.8.jar:6.1.8]

Solution

Adding 'public' before an interface class

public interface RepositoryService {

	@GetExchange("/repos/{owner}/{repo}")
	Repository getRepository(@PathVariable String owner, @PathVariable String repo);

	// more HTTP exchange methods...

}
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Feb 18, 2025
@sdeleuze sdeleuze self-assigned this Feb 18, 2025
@sdeleuze sdeleuze added type: documentation A documentation task in: web Issues in web modules (web, webmvc, webflux, websocket) and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Feb 18, 2025
@sdeleuze sdeleuze added this to the 6.2.4 milestone Feb 18, 2025
@sdeleuze
Copy link
Contributor

@Fabriceli I can't reproduce with a simple app, could you please share a reproducer?

@sdeleuze sdeleuze added the status: waiting-for-feedback We need additional information before we can continue label Feb 18, 2025
@Fabriceli
Copy link
Author

Fabriceli commented Feb 18, 2025

@Fabriceli I can't reproduce with a simple app, could you please share a reproducer?

Reproducer include 4 files:

  1. Demo.java
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@Slf4j
@SpringBootApplication
public class Demo {
    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(Demo20250211.class);
        application.run(args);
    }
}
  1. DemoController.java
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.support.WebClientAdapter;
import org.springframework.web.service.invoker.HttpServiceProxyFactory;

@Slf4j
@RestController
public class DemoController {

  @GetMapping("/proxy")
  public String proxy(){
    WebClient webClient = WebClient.builder().baseUrl("http://httpbin.org").build();
    WebClientAdapter adapter = WebClientAdapter.create(webClient);
    HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
    Httpbin service = factory.createClient(Httpbin.class);

      return service.getIp();
  }
}
  1. Httpbin.java
import org.springframework.web.service.annotation.GetExchange;

interface Httpbin {
    @GetExchange("/ip")
    String getIp();
}
  1. build.gradle
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-webflux'
}

If it can reproducer, could you assign it to me to fix?

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Feb 18, 2025
@sdeleuze
Copy link
Contributor

Since this has been created as an issue and is a simple change I had already locally, I pushed it myself. Next time, feel free to directly create a PR instead of an issue.

@sdeleuze sdeleuze removed the status: feedback-provided Feedback has been provided label Feb 18, 2025
pankratz76 pushed a commit to pankratz76/spring-framework that referenced this issue Feb 24, 2025
Closes spring-projectsgh-34443

Signed-off-by: Vincent Potucek <vincent.potucek@sap.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: documentation A documentation task
Projects
None yet
Development

No branches or pull requests

3 participants