1

When working with RMI (Remote Method Invocation), it is required for all methods defined in interfaces extending Remote to contain RemoteException in their throws clause.

For example, see the following Computing interface from this RMI tutorial.

public interface Compute extends Remote {
    <T> T executeTask(Task<T> t) throws RemoteException;
}

The problem is that the compiler does not check if the methods are defined correctly, instead an exception is thrown during the execution when the program encounters a method in a Remote interface that does not throw RemoteException.

It would be much better if such problems were discovered before the program is actually run. How can one write a test for that condition?


EDIT: I added a sample code to demonstrate the problem.

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>test</groupId>
  <artifactId>test</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>
    <dependency>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>rmic-maven-plugin</artifactId>
      <version>1.2.1</version>
    </dependency>
  </dependencies>
</project>

src/main/java/test/RemoteExample.java

package test;
import java.rmi.Remote;
public interface RemoteExample extends Remote {
  // the method does not throw RemoteException
  void action();
}

src/test/java/test/RemoteExampleTest.java

package test;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import org.junit.Test;

public class RemoteExampleTest {
  @Test
  public void test1() throws RemoteException {
    RemoteExample example = new RemoteExample() {
      public void action() {
        // do nothing
      }
    };
    // this fails
    RemoteExample exported = (RemoteExample) UnicastRemoteObject.exportObject(example, 0);
  }
}

mvn test fails, because the method RemoteExample.action() is declared in a Remote interface but does not throw RemoteException, therefore it can't be exported. However, if you add @Ignore before the test, maven build ends successfully, which implies that the condition was not tested.

I see a solution to write a custom test that would look at each Remote interface and would check if every method throws RemoteException, using reflection. But I believe there is a better approach.

jjurm
  • 501
  • 6
  • 11

1 Answers1

0

rmic checks it. You could incorporate rmic into your build. Make sure to delete the _stub.class files afterwards if you want to use dynamic stubs.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • I use Maven for building the project, so I added `rmic-maven-plugin` to the dependency list. But the condition is still not tested during the compilation. Is there anything specific to do in order to force `rmic` test the condition? – jjurm Dec 12 '16 at 09:17
  • It does so by default. Are you sure it's executing? and that you have `Remote` interfaces that should fail? NB you run it on the remote objects, not the interfaces. – user207421 Dec 12 '16 at 23:51
  • The point is that I want to test interfaces. Remote objects do not need to throw `RemoteException`. I do not think that in my configuration any tests other than mine are executing. I added a code to demonstrate the problem. – jjurm Dec 13 '16 at 10:27
  • The point is that `rmic` already tests it, as I already stated. I'm aware that you run it on remote objects, but if the remote interface(s) it implements has methods that don't throw `RemoteException` it will complain. You don't need to do anything further. – user207421 Sep 07 '20 at 04:56