Implement an EJB application consisting of remote session beans, persistent entity beans and a client.
The assignment uses a simple algorithm to measure distance between two nodes in a graph of objects, to mimic working with entities with relationships. Understanding the assignment requires no special knowledge.
As a technology for client/server architecture and data persistence, the assignment uses the Enterprise Java Beans standard, version 3.0. OpenEJB version 8.0 was chosen as a concrete implementation of the standard. The following knowledge is needed for the implementation:
javax.ejb.Remote
annotation).javax.ejb.Stateless
, implementing remote business interface).javax.persistence.Entity
) and specifying the mapping to a relational database via persistence.xml
.@PersistenceContext
annotation into the Stateless Session Bean.@OneToMany
, @ManyToMany
etc.).https://d3s.mff.cuni.cz/files/teaching/nswi080/labs/Files/sources-5.zip
The assignment consists of a simple algorithm to measure distance between two nodes in a graph. Graph nodes are represented by objects of the class Node
.
public class Node
{
private int id;
public Collection<Node> getNeighbors();
public void addNeighbor(Node neighbor);
}
The id
attribute is an unique number identifying the node. The addNeighbor()
method adds a node to the set of neighbors of the node and is used when a graph is being created. The getNeighbors()
method returns a set of all neighbors of the node and is used when measuring the distance. The measuring itself is provided by the Searcher
interface. The interface also provides methods for creating and connecting nodes, so that the client does not work directly with the Node
objects. The addNode()
method thus returns the id
of the newly created node, the getDistance()
and connectNodes()
methods expect the id’s of nodes to work with.
public interface Searcher
{
public static final int DISTANCE_INFINITE = -1;
public int getDistance(int nodeFrom, int nodeTo);
public int addNode();
public void connectNodes(int nodeFrom, int nodeTo);
}
Examine the provided local implementation of the assignment.
At first, implement the Searcher
as a Stateless Remote Bean and the Node
as an Entity Bean
with container-managed persistence, and the id
attribute as a primary key.
Represent the set of neighbors as a suitable relationship between entities.
Modify the client to create nodes and measure distances using a Searcher
deployed on the EJB server.
Verify that the Node
entities are persistent.
Add a command-line option to the client that will cause it to just run searches on the persisted graph without creating new nodes.
Extend the Searcher interface and change the implementation to offer working with persistent nodes to multiple clients simultaneously, so that each client has his own graph.
The id of the client will be provided as a command line argument.
Consider what is the best way of keeping track of client id (clients should not send their id on each request to the searcher) and how to change the attributes of the Node objects to allow storing independent graphs of multiple clients.
EJB server must be running (run-server.sh
)
~/OpenEJB/conf/ejbd.properties
port = XYZ
(XYZ>1024)admin.properties
(for stop-server
)props.put(Context.PROVIDER_URL, "ejbd://127.0.0.1:XYZ");
Server part deployed with run-deploy
-u
to undeploy the old version~/OpenEJB/data
stop-server
and delete the (hsqldb
) dataNode
Searcher
and class SearcherImpl
Main
(java Main
)SearcherImpl
Example
Jndi(name=<ClassName>Remote)
Main
ExampleClient
Searcher
instance retrieved by JNDI lookup
Movie
and Director
in Example
Node
id
with appropriate annotationSearcherImpl
ExampleEntityBeans
nodeMap
with EJB equivalentsEntityManager
unitName
- corresponds to persistence.xmlpersist()
for persistence of created Node
find()
for finding Node
by id
META-INF/persistence.xml
- see Example
id
for the second launch?
id
assignment to Node
Searcher
that selects a random id
from existing nodes