0

I work on two projects. one implementing the micro services using spring boot and the other the client in javaSE. on the server side I implement an RMI service that I export with RmiServiceExporter. client rating I invoke the service and when I call a data insertion method everything works but when I call a getter method to retrieve the data I have an exception and since I do not understand anything at all

Here is the code of my User class

@Entity
@Table(name = "sgsp_user")
public class User implements Serializable {
    @Id
    @Column(nullable=false,updatable = false)
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @Column(nullable = false,unique = true,name = "usr_name")
    private String username;
    @Column(nullable = false,name = "user_mdp")
    private String password;
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(
            name = "user_roles",
            joinColumns = @JoinColumn(name = "user_fk"),
            inverseJoinColumns = @JoinColumn(name = "roles_fk")
    )
    private List<Role> roles;
    private short status;
    private short activate;

    public User(String username, String password, short status, short activate) {
        this.username = username;
        this.password = password;
        this.status = status;
        this.activate = activate;
    }

    public User() {
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public List<Role> getRoles() {
        return roles;
    }

    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }

    public short getStatus() {
        return status;
    }

    public void setStatus(short status) {
        this.status = status;
    }

    public short getActivate() {
        return activate;
    }

    public void setActivate(short activate) {
        this.activate = activate;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return status == user.status &&
                activate == user.activate &&
                Objects.equals(id, user.id) &&
                Objects.equals(username, user.username) &&
                Objects.equals(password, user.password);
    }

    @Override
    public int hashCode() {

        return Objects.hash(id, username, password, status, activate);
    }
}

My service class

@Service
public class UserService {
 
    @Autowired
    private UserRepository userRepo;
 
    public User saveUser(User user){
        return this.userRepo.save(user);
    }
 
    public void deleteUser(Long id){
        this.userRepo.deleteById(id);
    }
    public void deleteUser(User user){
        this.userRepo.delete(user);
    }
 
    public User updateUser(User user){
        return this.userRepo.save(user);
    }
 
    public User getUser(String username,String password){
        return this.userRepo.getUserByUsernameAndPassword(username,password);
    }
 
    public Optional<User> getUser(Long id){
        return userRepo.findById(id);
    }
 
    public long countUser(Role role){
        return this.userRepo.count();
    }
 
    public boolean exist(String username){
        return (this.userRepo.getUserByUsername(username) != null);
    }
}

My Remote interface

public interface UserRemote extends Remote{

    public User saveUser(User user) throws RemoteException;

    public boolean connexion(String username, String password) throws RemoteException;

    public long countUsers(Role role) throws RemoteException;

    public boolean userExist(String username) throws RemoteException;

    public Optional<User> getUser(Long id) throws RemoteException;
}

My remote service class

@Component
public class UserRemoteService implements UserRemote {

    @Autowired
    private UserService userService;
    @Override
    public User saveUser(User user) throws RemoteException {
        return this.userService.saveUser(user);
    }

    @Override
    public boolean connexion(String username, String password) throws RemoteException {
        if(this.userService.getUser(username,password)!= null){
            return true;
        }else{
            return false;
        }
    }

    @Override
    public long countUsers(Role role) throws RemoteException {
        return this.userService.countUser(role);
    }

    @Override
    public boolean userExist(String username) throws RemoteException {
        return this.userService.exist(username);
    }

    @Override
    public Optional<User> getUser(Long id) throws RemoteException {
        return userService.getUser(id);
    }
}

The export class of services

@Configuration
public class ServiceRMIExporter {
 
    private int port = 5400;
 
    public SimpleJaxWsServiceExporter jaxWsServiceExporter(){
        return new SimpleJaxWsServiceExporter();
    }
 
    @Bean
    @Autowired
    public RmiServiceExporter getUserRemoteService(UserRemote userService){
        RmiServiceExporter exporter = new RmiServiceExporter();
        exporter.setService(userService);
        exporter.setServiceName("userservice");
        exporter.setRegistryPort(port);
        return exporter;
    }
}

in the end the customer

public class TestRmi {
 
    public static void main(String[] args) {
    try {
        UserRemote stub = (UserRemote) Naming.lookup("rmi://localhost:5400/userservice");
 
        Optional<User> usr = stub.getUser(1L);
 
        System.out.println(usr.toString());
    } catch (MalformedURLException | NotBoundException | RemoteException e) {
        e.printStackTrace();
        }       
    }
}

I use java.policy and java -Djava.security.manager -Djava.security.policy=C:\Users\Richie\IdeaProjects\sgsp\src\sgsp\admin\res\java.policy

without success

grant
{
        permission java.net.SocketPermission "*:80-65535","connect,accept,listen,resolve";
        permission java.security.AllPermission;
        permission java.net.SocketPermission "localhost:5400-", "listen";

};

the exception I get is the following :

java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
    java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: java.util.Optional
    at sun.rmi.server.UnicastRef.invoke(Unknown Source)
    at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
    at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
    at com.sun.proxy.$Proxy0.getUser(Unknown Source)
    at com.testRMI.TestRmi.main(TestRmi.java:19)
Caused by: java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: java.util.Optional
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at sun.rmi.server.UnicastRef.unmarshalValue(Unknown Source)
    ... 5 more
Caused by: java.io.NotSerializableException: java.util.Optional
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
    at sun.rmi.server.UnicastRef.marshalValue(UnicastRef.java:290)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:371)
    at sun.rmi.transport.Transport$1.run(Transport.java:200)
    at sun.rmi.transport.Transport$1.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Community
  • 1
  • 1
Bayless
  • 1
  • 5
  • Possible duplicate of [RMI JavaFX 2 - NotSerializableException error](https://stackoverflow.com/questions/15148121/rmi-javafx-2-notserializableexception-error) – user207421 Apr 11 '19 at 00:11
  • `Optional` is not`Serializable`. It's right there in the stack trace. – user207421 Apr 11 '19 at 00:12
  • thank you but I have a new problem when I integrate it in javafx. java.rmi.UnmarshalException: error unmarshalling return; nested exception is: java.lang.ClassNotFoundException: org.hibernate.collection.internal.PersistentBag (no security manager: RMI class loader disabled) ... I created a java.policy file at the root of my project and I added this line `-Djava.security.policy = \ java.policy` as argument of the program but it still does not work. here is the content of the java.policy file: grant { permission java.security.AllPermission "", ""; }; – Bayless Apr 11 '19 at 11:41

1 Answers1

0

I found a solution: I downloaded the jar file and placed in my client project and all worked: the files are as follows:

  • hibernate-core-5.3.7.Final
  • javax.persistence-api-2.2
  • javax.transaction-api-1.3
  • jboss-logging-3.3.2.Final

thank you for your attention

Bayless
  • 1
  • 5