Ok, let me see if I understand. you said, that
"The interface uses the enumeration and calls the EJB service to the backend with enum as a parameter. But the enumeration often changes, so we don’t want the backend to know its values."
When you say “values,” I assume that you are referring to the numeric value that you pass in the enumeration constructor, not the enumeration constants.
Therefore, this means that the interface and backend will have two different versions of the enum class, but the enumeration constants in them will be the same.
I assume that communication is via RMI (but this is not entirely clear in your post).
Enumeration serialization / deserialization now works differently than with other objects. According to the Java Serialization specification, when an enumeration is serialized, only its name is serialized. And when it is deserialized, it is created using the Enum.valueOf (name) method.
So, your original shell proposal will not work, because the server, due to the enums envisioned, will never know the actual value of the enumerations in the client.
On the bottom line, if you intend to transfer the enumeration to the server, there is no way to do what you pretend, because the values in the interface will never reach the backend, if serialization is meant.
If RMI is implied, a good solution would be to use code portability, so you could put the problematic class in the repository, accessible for both the server and the client, and when the front-end developers change the class definition, you can publish the class in the repository and server can get it from there.
See this article on dynamically loading code using the code base property in RMI http://download.oracle.com/javase/6/docs/technotes/guides/rmi/codebase.html
Another possible solution is that you can stop using Java Enum and use a Java class with finite constants, as it was before in the previous days before enumerations, and in this way you can guarantee that its values will be correctly serialized when they are are sent to the server.
Somewhat
public class Fruit implements Serializable{ private static final long serialVersionUID = 1L; public final Fruit ORANGE = new Fruit("orange"); public final Fruit LEMON = new Fruit("lemon"); private String name; private Fruit(String name){ this.name = name; } }
This way you can fully control what happens during deserialization, and your shell template can work that way.
This type of construction cannot completely replace an enumeration; for example, it cannot be used in switch statements. But if this is a problem, you can use this object as a parameter sent to the server and let the server rebuild the enumeration from it with its version of the enum class.
Thus, your listing may have two new methods: one for creating Java instances from the listing itself:
public static Fruit toFruit(FruitEnum enum); public FruitEnum valueOf(Fruit fruit);
And you can use them to convert versions and version settings for the server.