This is a Java library and annotation processor that allows you to define interfaces in a language-independent IDL, implement them in Java using stubs created by the processor, expose them over HTTP, and then invoke them remotely. Its key features are:
The IDL is independent of target language (as any good IDL should be), so it should be possible to generate (say) Python stubs to invoke a Java implementation. Note that only Java support is provided at the moment.
Remote invocations are REST-like, in that they are JSON messages over HTTP. Although this isn't nearly all there is to REST, it should be relatively transparent to (say) a Python programmer who is familiar with REST calls how to invoke a CARP object manually.
The server side can present sub-components under predictable URI sub-paths. For example, a root entity might contain and reference several services, each distinguishable by (say) UUID. It can arrange for remotely invokable objects to be created on-the-fly to represent each of these individually, and be discarded after a period of disuse, without having to create every single one, and bind it to the appropriate sub-path.
Rather than supporting exceptions, calls can have multiple return types. Having no return types permits one-way calls (in the CORBA sense).
Note that the annotation processor depends on certain compiler/IDE features. The only known IDE to work fully is NetBeans, as it supports annotation processing in the editor (so IDL stubs are available without a separate compilation stage), and the processor has access to the source path and class path (something that Eclipse doesn't seem to provide). OpenJDK javac also works. If you want to support other IDEs, you might have to factor out the stub generation as a separate project, so it can be compiled with javac, and the resultant jars alone imported into the IDE.
Here's an example interface definition:
type foo [ call bar { x, y : 1..50 } => okay => fail { reason : string }; call baz; ];
This translates to Java as: (abridged)
interface Foo { Bar bar(int x, int y); class Bar { static class Okay { } static class Fail { } } }
As a client, you can write:
Foo foo = ...; Foo.Bar bar = foo.bar(10, 20); if (bar.isOkay()) { ... } else { assert bar.isFail(); ... }
As a server, you can write:
public Bar bar(int x, int y) { if (false) { return Bar.Fail.reason("none, really").DONE(); } else { return Bar.Okay.DONE(); } }
See the Java documentation below for more details.