We’ll build a Java Method Server from scratch with real code, minimal theory, and plain English explanations. Perfect for beginners who want to see it working instead of reading endless jargon.
What is a Java Method Server
A Java Method Server is a Java program that executes methods on demand just like a REST API, but more flexible.
Instead of sending /api/add?a=5&b=3
, you send:
{
"methodName": "math.add",
"params": { "a": 5, "b": 3 }
}
The server finds your Java method, runs it, and returns the result:
{
"result": 8,
"error": null
}
So basically:
Clients send a method name.
The server calls that method.
The response goes back fast.
This idea powers systems like Documentum, SOAP, and even RMI, but you’ll learn a simpler, modern way.
How a Java Method Server Works
Let’s keep it visual and code-oriented.
Step | Description | Code / Concept |
---|---|---|
1 | Receive method request | JSON via /invoke |
2 | Find the right Java class | Use annotations or registry |
3 | Run the method | method.invoke() |
4 | Return the result | Send JSON back to client |
5 | Handle errors | Return "error" in response |
Create a Spring Boot Project
You can use Spring Initializr
Choose:
- Project: Maven
- Dependencies: Spring Web, Lombok
Then open it in your IDE (like IntelliJ or VS Code).
Define a Request and Response Model
We’ll use simple Java classes for input/output.
// InvokeRequest.java
public class InvokeRequest {
private String methodName;
private Map<String, Object> params;
// getters and setters
}
// InvokeResponse.java
public class InvokeResponse {
private Object result;
private String error;
public InvokeResponse(Object result, String error) {
this.result = result;
this.error = error;
}
// getters
}
Create an Interface for Method Handlers
Each “method” will implement a common interface.
public interface MethodHandler {
Object invoke(Map<String, Object> params) throws Exception;
}
We’ll annotate our method classes to register them automatically.
Add Custom Annotation
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MethodService {
String name();
}
Now we can tag each class with a readable method name.
Create a Simple Service
Let’s make a math service:
@MethodService(name = "math.add")
@Component
public class AddService implements MethodHandler {
@Override
public Object invoke(Map<String, Object> params) {
int a = (Integer) params.get("a");
int b = (Integer) params.get("b");
return a + b;
}
}
Easy! You can add more like math.subtract
, user.getInfo
, etc.
Build the Method Router
This is the heart of your Java Method Server it finds and calls the correct service.
@Service
public class MethodRouter {
private final Map<String, MethodHandler> registry = new HashMap<>();
@Autowired
public MethodRouter(List<MethodHandler> handlers) {
for (MethodHandler h : handlers) {
MethodService ann = h.getClass().getAnnotation(MethodService.class);
if (ann != null) {
registry.put(ann.name(), h);
}
}
}
public Object dispatch(String name, Map<String, Object> params) throws Exception {
MethodHandler handler = registry.get(name);
if (handler == null) throw new IllegalArgumentException("No method: " + name);
return handler.invoke(params);
}
}
Now the router knows about all available methods.
Create the Controller (API Endpoint)
This will expose one POST endpoint /invoke
to the outside world.
@RestController
public class ApiController {
@Autowired
private MethodRouter router;
@PostMapping("/invoke")
public ResponseEntity<InvokeResponse> invoke(@RequestBody InvokeRequest req) {
try {
Object result = router.dispatch(req.getMethodName(), req.getParams());
return ResponseEntity.ok(new InvokeResponse(result, null));
}
catch (Exception e) {
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new InvokeResponse(null, e.getMessage()));
}
}
}
Run the app → mvn spring-boot:run
Test It in Postman
Use:
POST http://localhost:8080/invoke
Content-Type: application/json
Body:
{
"methodName": "math.add",
"params": { "a": 10, "b": 20 }
}
Response:
{
"result": 30,
"error": null
}
You just built your first Java Method Server
Add More Methods
Example: Multiply numbers
@MethodService(name = "math.multiply")
@Component
public class MultiplyService implements MethodHandler {
public Object invoke(Map<String, Object> params) {
int a = (Integer) params.get("a");
int b = (Integer) params.get("b");
return a * b;
}
}
Restart the server, call "math.multiply"
, and you’re good to go!
Add Error Handling and Validation
Add a validator before dispatching:
if (req.getMethodName() == null || req.getMethodName().isEmpty()) {
throw new IllegalArgumentException("Missing method name!");
}
You can also catch specific exceptions in the router.
Add Thread Pool and Performance Boost
You don’t want your server to freeze on heavy tasks. Add async support:
@EnableAsync
@Configuration
public class AsyncConfig {
@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.initialize();
return executor;
}
}
In handlers:
@Async
public Object invoke(Map<String, Object> params) {
// long-running task
Add Logging and Monitoring
Use SLF4J or Micrometer:
private static final Logger log = LoggerFactory.getLogger(MethodRouter.class);
log.info("Invoking method: {}", name);
long start = System.currentTimeMillis();
Object result = handler.invoke(params);
log.info("Completed in {}ms", System.currentTimeMillis() - start);
You can later plug this into Prometheus or Grafana dashboards.
Add Security (JWT Example)
You can easily protect /invoke
:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeHttpRequests()
.anyRequest().authenticated()
.and()
.oauth2ResourceServer().jwt();
return http.build();
}
Add Dynamic Method Loading
You can go further and load classes dynamically:
Class<?> clazz = Class.forName(className);
Method method = clazz.getMethod(methodName, paramTypes);
Object instance = clazz.getDeclaredConstructor().newInstance();
Object result = method.invoke(instance, args);
Final Thought
Building a Java Method Server may sound complex at first, but once you dive into the code, you realize it’s just about connecting requests to methods in a clean, scalable way. With just a few lines of Java and a simple structure, you can handle multiple operations, reuse logic, and make your backend smarter. The best part? It grows with your needs from a single test project to a full-blown enterprise service. So, keep experimenting, refactor often, and remember: every great server starts with a single method call.