Monday, 13 December 2010

EL and UEL in JSP and JSF

JavaServer Pages (JSP) technology uses an expression language (EL) to access data from JSP pages. EL started out as the JavaServer Pages Standard Tag Library (JSTL), version 1.0 expression language, originally called SPEL (Simplest Possible Expression Language).

JavaServer Faces (JSF) technology enhances JSP with flexible and extensible UI component model, including:
  • a set of classes that define UI components.
  • a mechanism for handling events generated by the components.
  • a process for converting and validating component data. 
A separate EL was created for JavaServer Faces Technology, capable of:
  • wiring events generated by the components to server-side code.
  • binding the components to server-side data objects.
  • registering data validators and converters with the components.
Expression language used by the JSTL tags conflicted with that used by the component tags! Unifying these expression languages was highly desirable.

The new unified EL (UEL) essentially represents a union of the JSP and JavaServer Faces expression languages.

http://java.sun.com/products/jsp/reference/techart/unifiedEL.html

Thursday, 2 December 2010

What is Oracle ADF?

In my understanding, Oracle ADF (Application Development Framework) is a technology for visual and declarative Internet application development. This "conceptual framework" is  implemented by JDeveloper, Oracle's main IDE for Java EE programming. ADF encompasses, abstracts and sometimes re-defines a huge variety of concepts from all the different technologies used by a multiple-tier architecture, going from the database to JSF, through EJBs and Ajax (itself not a proper technology, but a combination of different Web programming techniques).

An Oracle White Paper, published in July 2009, describes the ADF architecture and its benefits over other frameworks (Oracle Application Development Framework Overview).

Still I have several puzzles, for instance: What are ADF business components? Enterprise JavaBeans? Something else or something more?

Wednesday, 17 November 2010

Arhive jar

Arhivele Java (fişiere cu extensia jar)sunt folosite pentru a împacheta într-un singur fişier mai multe clase Java (fişiere cu extensia class). Algoritmul de compresie folosit este algoritmul ZIP standard. În afară de clasele Java, o arhivă de tip jar mai poate conţine un director cu numele META-INF, în care se păstrează anumite fişiere de configurare şi fişierul MANIFEST.MF cu atribute referitoare la acel pachet (numele autorului, clasa principală, structura de directoare, etc.). Atât pentru crearea şi actualizarea arhivelor jar, cât şi pentru extragerea fişierelor din arhivă, se foloseşte comanda jar, care face parte din Java Development Kit. O arhivă JAR poate fi folosită direct în CLASSPATH, fără a fi necesară dezarhivarea şi listarea în CLASSPATH a tuturor componentelor din arhivă. Un fişier JAR poate fi executabil.

http://download.oracle.com/javase/tutorial/deployment/jar/basicsindex.html

http://www.herongyang.com/Java-Tools/jar-The-JAR-File-Tool.html

Thursday, 16 September 2010

Excellent Research Article

I read this morning an excellent research article on using Web 2.0 technologies in higher education: "Students' Acceptance of Web 2.0 Technologies in Higher Education: Findings from a Survey in a Romanian University", Proceedings DEXA 2010 Workshops, IEEE Computer Society Press (Elvira Popescu, SPeL2010), which I recommend for its content, as well as for its valuable bibliography.

As further reading, I am especially tempted by number 7 in this bibliography: M. Homola and Z. Kubincova, "Taking Advantage of Web 2.0 in Organized Education (A Survey)", Proc. ICL 2009, pp. 741-752.

I was not aware of the wealth of literature and preoccupation regarding the use of  Web 2.0 for learning and for research. Thank you, Elvira, for introducing me in this world!

Tuesday, 7 September 2010

Colecţii şi clase generice

Pachetul java.util conţine biblioteca API Collection (Collection Framework), în care sunt definite clase corespunzătoare unor structuri de date precum  Set, List, ArrayList, LinkedList, Vector, Map, Hashtable, Stack, etc. Aceste clase definesc metode de nivel înalt pentru căutarea şi sortarea elementelor lor. Obiectele claselor din cadrul de lucru pentru colecţii utilizează o referinţă Object pentru a indica spre elementele lor, astfel încât în cadrul aceleiaşi liste, de exemplu, se pot stoca tipuri diferite de obiecte, ca în programul Colectii redat mai jos.

Monday, 30 August 2010

Is Inversion of Control the Same Thing as Dependency Injection?

In the 2004 article Inversion of Control Containers and the Dependency Injection pattern, Martin Fowler discusses Dependency Injection vs. Service Locator patterns. The author states that Inversion of Control is too generic a term and settles for Dependency Injection. The answer to the question "Is Inversion of Control the Same Thing as Dependency Injection?" seems to be "Yes", at least as far as Java EE containers are concerned.

Wednesday, 16 June 2010

Specificarea relaţiilor dintre entităţile JPA

Există patru tipuri de relaţii între entităţile JPA, şi anume:

Relaţii ``unul cu unul'' (One-to-One)
Relaţii ``unul cu mai mulţi''(One-to-Many)
Relaţii ``mai mulţi cu unul''(Many-to-One)
Relaţii ``mai mulţi cu mai mulţi'' (Many-to-Many)

O relaţie poate fi unidirecţională sau bidirecţională. Într-o relaţie unidirecţională, una şi numai una dintre entităţi conţine un câmp care se referă la cealaltă entitate. Într-o relaţie bidirecţională, fiecare dintre entităţi conţine un câmp care se referă la cealaltă. Direcţia relaţiei dintre două entităţi determină posibilitatea unei interogări (query) de a naviga de la o entitate la cealaltă. Implementarea relaţiilor în contextul de persistenţă, care determină modul în care se fac actualizările în baza de date, se realizează prin adnotarea câmpurilor care se referă la entităţile relaţionate, în funcţie de tipul relaţiei, cu @OneToOne, @ManyToOne@OneToMany, @ManyToMany, @JoinColumn, @JoinTable, etc.

Exemple

@Entity
@Table(name="CURSURI")

@NamedQueries({
@NamedQuery(name="Cursuri.numeTitular",
    query="select o.profesor from Cursuri o " +
          "where o.cursId = :param"),
@NamedQuery(name="Cursuri.studentiInscrisi",
        query="select o.studenti from Cursuri o " +
          "where o.cursId = :param")
})

public class Cursuri implements Serializable{

@Id
@Column(name="CURSID", nullable=false)
private int cursId;

@Column(name="NUME")
private String nume;

//mai multe cursuri la un profesor

@ManyToOne
@JoinColumn(name="PROFESORID",referencedColumnName="PROFESORID")
private Profesori profesor;


//mai multe cursuri la un student, mai multi studenti la un curs
@ManyToMany
@JoinTable(name="STUD_CURS",
       joinColumns=
           @JoinColumn(name="CURSID",referencedColumnName="CURSID"),
       inverseJoinColumns=
           @JoinColumn(name="STUDENTID",referencedColumnName="STUDENTID"))
//name=numele coloanei din tabela STUD_CURS (tabela de join)
//referencedColumnName=numele coloanelor din tabelele CURSURI, respectiv STUDENTI
private List studenti;

...

@Entity
@Table(name="STUDENTI")

@NamedQuery(name="Studenti.note",
    query="select o.note from Studenti o " +
          "where o.studentId = :param")

public class Studenti implements Serializable{

@Id
@Column(name="STUDENTID", nullable=false)
private int studentId;

@Column(name="NUME")
private String nume;

@Column(name="PRENUME")
private String prenume;

@Column(name="EMAIL")
private String email;

@OneToOne
@JoinColumn(name="STUDENTID",referencedColumnName="STUDENTID")
private Note note;

...

@Stateless(name="FatadaCursuri")
public class FatadaCursuriBean implements FatadaCursuri{

@PersistenceContext(unitName="CelestePersistUnit")
EntityManager em;

public String cautaTitular(int id){

Profesori titular = (Profesori)em.createNamedQuery("Cursuri.numeTitular").
            setParameter("param",id).getSingleResult();

return titular.citesteNume();

}

public List cautaStudenti(int idCurs){

List listaStudenti = (List)em.createNamedQuery("Cursuri.studentiInscrisi").setParameter("param",idCurs).getResultList();
return listaStudenti;

}

public Note cautaNote(int idStud){

Note note = (Note)em.createNamedQuery("Studenti.note").
            setParameter("param",idStud).getSingleResult();

return note;

}

public List getGradesforOneStudent(int idStud){
List note = (List)em.createNamedQuery("Grades.forOneStudent").
            setParameter("param",idStud).getResultList();

return note;
}

}

Tuesday, 1 June 2010

Gestiunea tranzacţiilor

În limbajul ingineriei software tranzacţiile reprezintă tehnologia care asigură integritatea datelor, controlând accesul concurent la date şi împiedicând actualizarea parţială în cazul apariţiei unei erori în mijlocul execuţiei unui program. Putem defini o tranzacţie ca pe un grup de operaţii dintre care fie se execută toate, fie nu se execută niciuna. O tranzacţie este o unitate indivizibilă de lucru (unit of work).
 
De exemplu, într-o aplicaţie de eLearning, modificarea unei note poate necesita mai mulţi paşi:

begin
  modifica nota
  recalculeaza media
  refa clasamentul
commit

O tranzacţie trebuie să fie atomică (se execută în totalitate sau nu se execută deloc), consecventă (păstrează integritatea bazei de date), izolată (stările intermediare ale sistemului nu sunt vizibile în exterior pâna la încheierea tranzacţiei) şi durabilă (înainte de încheierea tranzacţiei, modificările efectuate de aceasta vor fi scrise într-o memorie fizică, astfel încât să poată fi recuperate chiar în cazul unei căderi a sistemului) (ACID).

Tranzacţii gestionate de container

Într-o componentă de tip sesiune sau bazată pe mesaje care nu specifică tipul de gestiune a tranzacţiilor, codul pe care îl scrieţi nu va conţine instrucţiuni care să marcheze începutul sau sfârşitul tranzacţiilor, acestea fiind setate de către container. Containerul va începe, suspenda şi încheia tranzacţiile în funcţie de valoarea unui atribut specificat pentru fiecare metodă cu adnotarea @TransactionAttribute. Valoarea acestui atribut poate fi una dintre următoarele: REQUIRED, REQUIRES_NEW, MANDATORY, NOT_SUPPORTED, SUPPORTS, NEVER.

Semnificaţiile acestor valori sunt explicate în detaliu aici: http://java.sun.com/javaee/6/docs/tutorial/doc/bncij.html

Tranzacţii gestionate de componente

Interfaţa de programare JTA (Java Transaction API) defineşte metode pentru iniţierea şi terminarea explicită a tranzacţiilor (begin, commit, rollback).

Monday, 31 May 2010

Querying the database with JPA

When working with entity beans you can retrieve records from the database using Java Persistence Query Language (JPQL), a declarative language similar to SQL but which works with Java objects rather than relational tables. Both dynamic and static queries can be defined with JPQL. Static queries (named queries) are defined in a JPA entity nested within a @NamedQuery annotation. Dynamic queries are defined directly within an application's business logic. The EntityManager interface provides the methods createQuery and createNamedQuery used to create dynamic, respectively static queries.
The Java EE 6 Tutorial presents JPQL in detail. (http://java.sun.com/javaee/6/docs/tutorial/doc/bnbrg.html)

Wednesday, 19 May 2010

Composite Primary Keys for JPA Entities

When the primary key of a JPA entity is composed from more than one attribute it is necessary to define a class corresponding to the primary key.

The JPA entity will use the @IdClass annotation to specify the name of the class corresponding to the composite primary key.

In the class corresponding to the JPA entity, the attributes included in the primary key will be marked with the @Id annotation.

Example using a compound primary key in JPA

1.Create and populate a table to be used by the example.

ij> CREATE TABLE Grades(
> studentID INTEGER NOT NULL,
> cursID INTEGER NOT NULL,
> semestrul1 INTEGER,
> semestrul2 INTEGER,
> laborator INTEGER,
> CONSTRAINT pk_SidCid PRIMARY KEY(studentID,cursID));
0 rows inserted/updated/deleted
...
ij> INSERT INTO Grades VALUES
> (1,1,9,10,10);
1 row inserted/updated/deleted
...
 ij> SELECT * FROM Grades;
STUDENTID  |CURSID     |SEMESTRUL1 |SEMESTRUL2 |LABORATOR
-----------------------------------------------------------
1          |1          |9          |10         |10
2          |1          |8          |7           |8
3          |1          |10         |10        |10
28 rows selected

2.Define the JPA entity

import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Column;
import javax.persistence.NamedQuery;
import java.io.Serializable;

@Entity
@Table(name="GRADES")
@IdClass(GradesPK.class)
@NamedQuery(name="Grades.forOneStudent",
query="select o from Grades o where o.studentId=:param")

public class Grades implements Serializable{

@Id
@Column(name="STUDENTID", nullable=false)
private int studentId;

@Id
@Column(name="CURSID", nullable=false)
private int cursId;

@Column(name="SEMESTRUL1")
private int semestrul1;

...
}

3.Define the class corresponding to the primary key.

Make sure that the names and types of the fields are the same with those in the entity bean!

import java.io.Serializable;

public class GradesPK implements Serializable{

public int studentId;
public int cursId;

public GradesPK(){
//constructor public fara parametri
}

public GradesPK(int studentId, int cursId){
this.studentId=studentId;
this.cursId=cursId;
}

public int hashCode(){
return super.hashCode();
}

public boolean equals(Object other){

if(!(other instanceof GradesPK)){
return false;}

GradesPK celalalt = (GradesPK)other;

return(celalalt.studentId==studentId
       &&
      celalalt.cursId==cursId);
}
}

4.Define a method in a session bean to use for testing a query.

public List getGradesforOneStudent(int idStud){
List note = (List)em.createNamedQuery("Grades.forOneStudent").
            setParameter("param",idStud).getResultList();

return note;
}


5.Write a test client to call the method.
 
import javax.naming.InitialContext;
import java.util.List;
import java.util.ListIterator;
...

public class Client1{
public static void main(String[] args) throws Exception
{
    InitialContext ctx = new InitialContext();
    FatadaCursuri beanInstance = (FatadaCursuri)
                                      ctx.lookup(FatadaCursuri.class.getName());

    List grades = beanInstance.getGradesforOneStudent(2);
    ListIterator listIterator2 = grades.listIterator();
    System.out.println("Notele studentului cu studentId=2");
    while(listIterator2.hasNext()){
    Grades linie = (Grades)listIterator2.next();
    System.out.print("ID Curs:"+linie.citesteCursId());
    System.out.print(" Nota 1:"+linie.citesteSemestrul1());
    System.out.print(" Nota 2:"+linie.citesteSemestrul2());
    System.out.println(" Nota lab.:"+linie.citesteLaborator());   
    }
}
}

Monday, 17 May 2010

Ciclul de viaţă al componentelor de tip sesiune

O componentă de tip sesiune fără stare este creată la iniţiativa containerului EJB. Containerul menţine un rezervor (pool) de instanţe ale componentelor de acest tip, astfel încât atunci când un client apelează o metodă a unei componente de tip sesiune fără stare este aleasă o instanţă a componentei din rezervor şi invocată metoda acesteia. Acest lucru este posibil deoarece starea componentei nu trebuie menţinută după încheierea execuţiei metodei. Distrugerea componentelor de tip sesiune fără stare este deasemenea efectuată prin decizia containerului EJB, de exemplu pentru eliberarea unor resurse de memorie sau atunci când o anumită componentă nu este utilizată un timp mai îndelungat. Astfel, o componentă de tip sesiune fără stare se poate găsi în timpul ciclului său de viaţă doar într-una din două stări: inexistentă şi în aştepare(ready).

O metodă a unei componente de tip sesiune fără stare poate fi marcată cu una dintre adnotările @PostConstruct sau @PreDestroy, ceea ce va face ca ele să fie apelate imediat după instanţierea componentei, respectiv înainte de distrugerea ei.

Spre deosebire de cazul componentelor fără stare, ciclul de viaţă al componentelor de tip sesiune cu stare este iniţiat de către clienţi prin solicitarea unei referinţe la o instanţă a unei componente. Pe durata ciclului său de viaţă, o componentă de tip sesiune cu stare poate fi trecută de către container din starea ready, în care componenta se află în memoria principală, într-o stare pasivă(inactivă), în memoria secundară a serverului. Re-activarea are loc atunci când un client apelează o metodă a unei instanţe pasive. Reamintiţi-vă că o componentă de tip sesiune cu stare este asociată unui client pentru toată durata conversaţiei acestuia cu serverul, care poate conţine mai multe apeluri de metode, între care trebuie păstrată starea componentei. Prin urmare o componentă de tip sesiune cu stare nu va fi în general distrusă la iniţiativa containerului! (Se poate ca o componentă de tip sesiune cu stare, pasivă, să fie distrusă de container după o perioadă îndelungată de inactivitate a clientului, timeout.)

Adnotările care pot marca una dintre metodele unei componente de tip sesiune cu stare sunt:  @PostConstruct, @PreDestroy, @PrePassivate şi @PostActivate, cu semnificaţiile evidente date de numele lor.

Tuesday, 4 May 2010

Componente bazate pe mesaje (Message Driven Beans)

O componentă bazată pe mesaje (message-driven bean, MDB) este o componentă fără stare care consumă mesaje dintr-o coadă JMS (Java Message Service). Standardul JMS este parte integrantă din Java EE şi implementează suportul pentru comunicaţii asincrone pe această platformă. Mai concret, este vorba despre dirijarea mesajelor către destinaţii denumite cozi şi distribuirea acestor mesaje către consumatori.

O componentă MDB defineşte o metodă, onMessage(), care este apelată de către containerul EJB ori de câte ori este primit un mesaj în coada la care este asociată componenta. O componentă de tip MDB nu poate fi apelată direct de către clienţi.

Resursele necesare transmiterii mesajelor folosind JMS sunt:
- un obiect de tip ConnectionFactory, care conţine parametrii pentru configurarea conexiunii. Acest obiect este folosit de clienţi la crearea conexiunilor cu providerul de JMS.
- un obiect de tip Queue, coada propriu-zisă de mesaje.
- o destinaţie fizică.

Cele trei resurse pot fi create folosind consola grafică de administrare a serverului de aplicaţii, ca în imaginile de mai jos.


Ca exerciţiu, am creat fişierul PrimaCBM.java, cu următorul conţinut:

import javax.ejb.MessageDriven;
import javax.jms.MessageListener;
import javax.jms.Message;
import javax.jms.TextMessage;
import java.util.logging.Logger;

@MessageDriven(name="PrimaCBM",mappedName="jms/Queue")
public class PrimaCBM implements MessageListener {
    static final Logger registru = Logger.getLogger("PrimaCBM");
   
    public PrimaCBM(){}

    public void onMessage(Message mesaj) {
        try {         
           String text = mesaj.getStringProperty("text");
           registru.info("CBM a primit mesajul:"+text);
            }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

La primirea unui mesaj containerul apelează metoda onMessage(). Vom înregistra primirea mesajului într-unul dintre fişierele de jurnalizare ale serverului de aplicaţii. În acest scop folosim un obiect de tipul Logger, definit în pachetul java.util.logging. Conţinutul fişierului de jurnalizare poate fi vizualizat şi prin intermediul consolei grafice de administrare a serverului.

Compilaţi componenta şi construiţi arhiva CBM.jar, folosind următoarele comenzi:

C:\EJB>javac -classpath .;C:\glassfishv3\glassfish\lib\javaee.jar PrimaCBM.java

C:\EJB>jar cvf CBM.jar PrimaCBM.class

Încărcaţi arhiva CBM.jar pe serverul de aplicaţii, folosind consola grafică de administrare şi specificând tipul arhivei ca fiind EJB Jar.

Pentru a trimite mesaje către componenta definită am creat programul CBMClient.java, a cărui sursă este redată mai jos.

import javax.jms.ConnectionFactory;
import javax.jms.Queue;
import javax.jms.Connection;
import javax.jms.Session;
import javax.jms.MessageProducer;
import javax.jms.TextMessage;
import javax.jms.Message;

import javax.naming.InitialContext;


public class CBMClient {

public static void main(String[] args) {

System.out.println("Hi!");

try {

    InitialContext ctx = new InitialContext();
    System.out.println("S-a creat InitialContext"); 
    ConnectionFactory connectionFactory =
(ConnectionFactory) ctx.lookup("firstJMS_pool");
    System.out.println("S-a creat ConnectionFactory");
    Queue coadaMesaje = (Queue) ctx.lookup("jms/Queue");
    System.out.println("S-a creat Queue"); 

    Connection conexiune = null;
    Session sesiune = null;
    MessageProducer expeditor = null;
    Message mesaj = null;

conexiune = connectionFactory.createConnection();
    System.out.println("S-a creat conexiunea");

sesiune = conexiune.createSession(false, Session.AUTO_ACKNOWLEDGE);
expeditor = sesiune.createProducer(coadaMesaje);
mesaj = sesiune.createMessage();

mesaj.setStringProperty("text","Testez CBM");

    expeditor.send(mesaj);

System.out.println("Am trimis mesajul:"+mesaj.getStringProperty("text"));

    expeditor.close();
    sesiune.close();
    conexiune.close();
}
catch(Exception e){System.out.println("Exceptie: " + e.toString());}
} // main
} // class


Compilaţi şi executaţi programul client folosind următoarele comenzi:

C:\EJB\clienti>javac -classpath .;C:\glassfishv3\glassfish\lib\javaee.jar CBMClient.java

C:\EJB\clienti>java -classpath .;C:\glassfishv3\glassfish\lib\appserv-rt.jar;C:\glassfishv3\glassfish\lib\install\applications\jmsra\imqjmsra.jar;C:\glassfishv3\glassfish\lib\appserv-admin.jar;C:\glassfishv3\glassfish\lib\appserv-ws.jar;C:\glassfishv3\glassfish\lib\javaee.jar CBMClient


Mesajul primit înregistrat în fişierul de jurnalizare poate fi văzut şi prin intermediul consolei grafice de administrare a serverului, aşa cum este ilustrat în imaginile de mai jos.


Friday, 23 April 2010

Entităţi JPA în Java EE 6

Clasa corespunzătoare unei tabele relaţionale

Java EE foloseşte standardul JPA(Java Persistence API) pentru realizarea corespondenţei dintre obiecte Java şi tabele ale unei baze de date relaţionale. Între aplicaţie, care foloseşte modelul bazat pe obiecte, şi schema bazei de date există în Java EE un nivel numit ``de persistenţă'', care izolează programatorul de problemele specifice bazei de date (e.g. gestiunea tranzacţiilor). O tabelă dintr-o bază de date relaţională este reprezentată în program printr-o entitate JPA, o clasă Java marcată cu adnotarea @Entity.

O instanţă a unei entităţi JPA corespunde unei linii din tabela asociată.

Corespondenţa dintre o entitate JPA şi o tabelă din baza de date se realizează folosind adnotări în clasa Java care reprezintă entitatea JPA. Astfel, de exemplu, @Table specifică numele tabelei cu care entitatea este asociată, @Column desemnează numele coloanei din tabelă cu care este asociat câmpul marcat al entităţii JPA, @Id marchează un câmp al entităţii care corespunde unei chei primare in tabela asociată.

Mai jos se găseşte definiţia clasei Student, entitatea JPA corespunzătoare unei tabele STUDENT.

package doi;

import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Id;
import javax.persistence.Column;
import java.io.Serializable;

@Entity
@Table(name="STUDENT")

public class Student implements Serializable{

@Id
@Column(name="STUDENTID", nullable=false)
private int studentId;

@Column(name="NUME")
private String nume;

@Column(name="PRENUME")
private String prenume;

@Column(name="EMAIL")
private String email;

public Student(){
}

public long citesteStudentId(){
return studentId;
}
public void scrieStudentId(int i){
studentId=i;
}
public String citesteNume(){
return nume;
}
public void scrieNume(String n){
nume=n;
}
public String citestePrenume(){
return prenume;
}
public void scriePrenume(String p){
prenume=p;
}
public String citesteEmail(){
return email;
}
public void scrieEmail(String e){
email=e;
}
}

Componenta de tip sesiune, faţada componentei de tip entitate 

Găsirea, actualizarea, crearea şi ştergerea obiectelor asociate cu linii dintr-o tabelă relaţională (găsirea, actualizarea, crearea şi ştergerea entităţilor JPA) se face prin intermediul unor metode specificate de interfaţa EntityManager, care face parte din standardul JPA.

Pentru a obţine o instanţă de tip EntityManager se foloseşte adnotarea @PersistenceContext pentru a injecta gestionarul de entităţi JPA în componenta care operează cu entităţi JPA.

Accesul la o componentă de tip entitate este implementat prin intermediul unei componente de tip sesiune. Definim în continuare interfaţa şi clasa corespunzătoare componentei CautaStudent, o componentă de tip sesiune, fără stare, care defineşte metoda cauta(int id). Rezultatul metodei cauta reprezintă numele studentului cu id-ul dat ca argument, obţinut prin folosirea metodei find() a gestionarului de entităţi em. La apelul metodei find(), gestionarul de entităţi extrage înregistrarea căutată din baza de date şi instanţiază cu valorile obţinute un obiect de tipul corespunzător (în exemplul nostru de tipul Student).

Definiţia interfeţei

package doi;

import javax.ejb.Remote;
import doi.Student;

@Remote
public interface CautaStudent{
public String cauta(int id);
}

Definiţia clasei

package doi;

import javax.ejb.Stateless;
import javax.annotation.Resource;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceUnit;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

import doi.Student;

@Stateless(name="CautaStudent")
public class CautaStudentBean implements CautaStudent{

@PersistenceContext(unitName="StudentPersistUnit")
EntityManager em;

public String cauta(int id){
Student s = em.find(Student.class,id);
return s.citesteNume();
}
}

Compilaţi entitatea JPA, interfaţa şi clasa corespunzătoare componentei de tip sesiune, folosind următoarele comenzi:

C:\EJB>set CLASSPATH=.;C:\glassfishv3\glassfish\lib\javaee.jar

C:\EJB>javac -d . doi/Student.java

C:\EJB>javac -d . doi/CautaStudent.java

C:\EJB>javac -d . doi/CautaStudentBean.java

Definirea unităţii de persistenţă

O unitate de persistenţă defineşte mulţimea tuturor entităţilor JPA dintr-o aplicaţie administrate de instanţe de tipul EntityManager şi specifică numele global JNDI al sursei de date corespunzătoare. Unităţile de persistenţă sunt definite în fişierul de configurare persistence.xml, care trebuie să se găsească în directorul META-INF al unei arhive EJB-JAR.

Pentru exemplul considerat am creat în directorul C:\EJB\META-INF fişierul persistence.xml redat mai jos, care specifică numele sursei de date folosite de către containerul EJB (jdbc/student) şi numele clasei de persistenţă gestionată de EntityManager (doi.Student).

<persistence>
<persistence-unit name="StudentPersistUnit">
<description>
Prima unitate de persistenta.
Administreaza date referitoare la studenti.
</description>
<jta-data-source>jdbc/student</jta-data-source>
<class>doi.Student</class>
</persistence-unit>
</persistence>

Construiţi arhiva MyStudentApp.jar folosind următoarea comandă:

C:\EJB> jar cvf MyStudentApp.jar doi/CautaStudent.* doi/CautaStudentBean.* doi/Student.* META-INF/persistence.xml

Încărcaţi arhiva MyStudentApp.jar pe serverul de aplicaţii, folosind consola grafică de administrare şi specificând tipul arhivei ca fiind EJB Jar.

Un exemplu de client

package clienti;

import doi.CautaStudent;
import javax.naming.InitialContext;
import doi.Student;

public class EntityBeanStudentClient{
public static void main(String[] args) throws Exception
{
InitialContext ctx = new InitialContext();
CautaStudent beanInstance = (CautaStudent)
                            ctx.lookup(CautaStudent.class.getName());
String myName=beanInstance.cauta(777);
System.out.println("Hi, "
                   + myName + "!");
}
}

Compilaţi şi executaţi programul client folosind următoarele comenzi:

C:\EJB>javac -d . clienti/EntityBeanStudentClient.java

C:\EJB>java -classpath C:\glassfishv3\glassfish\lib\appserv-rt.jar;C:\glassfishv3\glassfish\lib\javaee.jar;. clienti.EntityBeanStudentClient

Monday, 19 April 2010

Blog Companion Google Group

I created a companion Google Group, so that I can upload files and you can ask questions or comment independently of my posts.

The group name is Cristina's Java EE Blog Companion and it can be accessed at the address http://groups.google.com/group/java-ee-blog-companion.

Anybody can view group content but only members can post messages. If you want to be a member, please let me know.

Wednesday, 14 April 2010

Definirea unei surse de date Java DB in GlassFish V3

Crearea şi distrugerea conexiunilor la o bază de date poate fi costisitoare, ceea ce justifică menţinerea unui "rezervor de conexiuni'' (connection pool), o mulţime de conexiuni reutilizabile, pentru o anumită bază de date, pregătite în prealabil şi administrate de către serverul de aplicaţii. Definiţia unei surse de date în GlassFish trebuie să fie precedată de definiţia rezervorului de conexiuni folosit de aceasta. Am definit rezervorul de conexiuni şi sursa de date folosind consola grafică pentru administrare a serverului, aşa cum se vede în figurile următoare.

 Pentru ca definiţia unui rezervor de conexiuni pe o bază de date Java DB să fie completă trebuie definite şi următoarele proprietăţi: DatabaseName, User, Password, PortNumber, ServerName. Mai jos este specificat ca exemplu un set de valori pentru aceste proprietăţi.

DatabaseName = C:\Sun\SDK\javaDB\bin\student
User = profesor
Password = parolaprofesor
PortNumber = 1527
ServerName = localhost

Monday, 12 April 2010

Build and Test a Simple Session Bean Revisited

Pentru a testa funcţionarea componentei se vor parcurge următorii paşi:

1. C:\EJB>set CLASSPATH=.;C:\glassfishv3\glassfish\lib\javaee.jar

2. Se compilează interfaţa componentei, clasa care o implementează şi programul client:

C:\EJB>javac -d . firstBean/*.java

C:\EJB>javac -d . firstBeanClient/*.java

3. Se împachetează clasa şi interfaţa corespunzătoare componentei de tip sesiune în arhiva FirstBeanJar.jar:

C:\EJB>jar cvf FirstBeanJar.jar firstBean\

4. Se încarcă arhiva FirstBeanJar.jar pe serverul de aplicaţii, folosind, de exemplu, consola grafică de administrare:

















5. Se execută programul client:

C:\EJB>java -classpath C:\glassfishv3\glassfish\lib\appserv-rt.jar; C:\glassfishv3\glassfish\lib\javaee.jar; C:\EJB firstBeanClient.FirstBeanClient Cristina

Implicit serverul de aplicaţii se găseşte pe maşina locală, comanda precedentă fiind echivalentă cu următoarea:

C:\EJB>java -classpath C:\glassfishv3\glassfish\lib\appserv-rt.jar; C:\glassfishv3\glassfish\lib\javaee.jar; C:\EJB -D org.omg.CORBA.ORBInitialHost = localhost firstBeanClient.FirstBeanClient Cristina

Sunday, 11 April 2010

O aplicaţie simplă cu Java DB

import java.sql.*;

public class Student {

public static void main(String[] args) {

Connection dbConnection = null;     
String dbUrl =
"jdbc:derby:C:\\Sun\\SDK\\javadb\\bin\\student;"+
"user=profesor;password=parolaprofesor";

try{
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
//incarca driver JDBC pt JavaDB
}

catch(ClassNotFoundException e) {
e.printStackTrace(); 
System.out.println("Eroare incarcare driver!\n" + e);
}

try{
dbConnection=DriverManager.getConnection(dbUrl);
Statement stmt= dbConnection.createStatement();
ResultSet  rs =
stmt.executeQuery(
" SELECT * FROM student");

while (rs.next()) {
System.out.println (
rs.getString ("nume") + "," +
rs.getString ("prenume") + "," +
rs.getString ("email"));
}
stmt.close();
}

catch(SQLException e) {
e.printStackTrace();
}
}
}
Programul se execută precizând în linia de comandă pentru maşina virtuală Java calea către driverul Java DB pentru SQL(derby.jar):

java -classpath .;C:\Sun\SDK\javadb\lib\derby.jar Student

Wednesday, 7 April 2010

Introducere în Java DB

Java DB este o versiune a sistemului Derby(Apache) pentru baze de date. Această versiune este dezvoltată în întregime în tehnologie Java şi este în prezent "împachetată" în serverul de aplicaţii GlassFish.

Execuţia comenzilor SQL

Instrumentul pe care îl avem la dispoziţie pentru execuţia comenzilor SQL în Java DB, atât a comenzilor de interogare cât şi a celor de creare a tabelelor şi manipulare a datelor, se numeşte ij. Interfaţa utilizatorului cu ij este linia de comandă.

Pe calculatorul meu, ij se găseşte în directorul C:\Sun\SDK\javadb\bin. Pentru a deschide o conexiune la baza de date, a crea o tabelă şi a insera valori în aceasta am executat următoarele comenzi:

C:\Sun\SDK\javadb\bin>ij

ij>connect 'jdbc:derby:student;
create=true; user=profesor;
password = parolaprofesor'
as my_connection;

ij>CREATE TABLE t1(
nume VARCHAR(30),
varsta INTEGER);

ij>INSERT INTO t1 VALUES
('Cristina',31);

ij>SELECT * FROM t1;

ij>exit;

C:\Sun\SDK\javadb\bin>

Thursday, 18 February 2010

Lesson One: Build and Test a Simple Session Bean in 8 Easy Steps

A session bean implies a class and an interface.

1. Define the interface in a file named Salut.java
package firstBean;
import javax.ejb.Remote;

@Remote
public interface Salut{
public String saluta(String nume);
}

2.Define the class in a file named SalutEJB.java
package firstBean;
import javax.ejb.*;

@Stateless
public class SalutEJB implements Salut{
public String saluta(String nume){
return "Salut,"+nume+"!";}
}
3. Compile the class and the interface
>set CLASSPATH=.;C:\Sun\SDK\lib\javaee.jar
>javac -d . firstBean/*.java

4.Write a client for the session bean, in a file named FirstBeanClient.java

package firstBeanClient;

import firstBean.Salut;
import javax.naming.InitialContext;

public class FirstBeanClient{
public static void main(String[] args) throws Exception
{
InitialContext context = new InitialContext();
Salut beanInstance = (Salut) context.lookup("firstBean.Salut");
System.out.println(beanInstance.saluta(args[0]));
}
}

5.Compile the client
>javac -d . firstBeanClient/*.java

6.Build a jar archive containing the session bean (class and interface)
>jar cvf FirstBeanJar.jar firstBean\

7.Load the archive (FirstBeanJar.jar) to the application server (I use GlassFish and its graphical administration console)

8. Execute the client including appserv-rt.jar and javaee.jar in the classpath.
>java -classpath C:\Sun\SDK\lib\appserv-rt.jar; ->
->C:\Sun\SDK\lib\javaee.jar; ->
C:\EJB firstBeanClient.FirstBeanClient Cristina

Thursday, 11 February 2010

Motivation

I have been asked how is my book going to be different from other Java EE books. The answer is I am going to concentrate on clarifying concepts, rather than giving "how to do" recipes. In my opinion, this approach will prepare the learner to switch between different versions of the platform or of the application server, without major difficulty.

Tuesday, 9 February 2010

The first step


I am currently writing a book on programming with Enterprise JavaBeans. I intend to support the readers during their learning process using this blog.
Many thanks to Professor Naotugu Nozue, my main PhD advisor, and his wife, Mrs. Misako Nozue, who encouraged me to achieve this project during their recent visit to Romania. The picture represents Professor and Mrs. Nozue, my friend Mihai and myself at the table where I launched the idea.

Tuesday, 5 January 2010

Introduction

This is the translation in English of my previous post.

Java EE is a programming technology for information systems based on application servers. This technology uses various types of software components managed by the application server which act like mediators between client programs and other specialized servers (e.g. database servers). While Java is a programming language, Java EE is a standard specifying, on one hand, the way of developing systems based on application servers, on the other hand the "services" that the application server must provide in order for the application to be independent of the application server. "Services" mentioned in the previous sentence should not make the reader think about Web services, the meaning intended being a more general one, that is of functions or methods that are available to the applications in the environment created by the application server. The principle "write once, run everywhere" is valid for Java EE applications as well, that is any application that conforms to the standard should run as well with Oracle WebLogic, IBM WebSphere, Sun GlassFish, etc. (the previous enumeration represents the most well-known application servers as of now).

The architecture of Java EE applications is developed in three tiers: client, application server, database, and represents an evolution of older client-server type architectures. Generally, a Java EE application can be viewed as four-tiered, because inside the application server there are two containers, one to manage Web components (JSP and JSF pages) and another to manage EJB (Enterprise JavaBeans) components.

Introducere

Java EE(Enterprise Edition) reprezintă o tehnologie de programare a sistemelor bazate pe servere de aplicaţii. Această tehnologie foloseşte diferite tipuri de componente software administrate de către serverul de aplicaţii, care acţionează ca intermediari între programele clienţilor şi alte servere specializate (de exemplu servere de baze de date). Dacă Java este un limbaj de programare, Java EE este un standard care specifică, pe de o parte, modul de realizare a sistemelor bazate pe servere de aplicaţii, pe de altă parte modul de funcţionare al serverului de aplicaţii şi ``serviciile'' pe care acesta trebuie să le pună la dispoziţie, asfel încât aplicaţia să fie independentă de serverul de aplicaţii. Am inclus cuvântul ``servicii'' între ghilimele, astfel încât el să nu ducă cititorul cu gândul la noţiunea de ``servicii Web'', ci să fie luat în sensul său mai general, de funcţii sau metode pe care aplicaţiile le au la dispoziţie în mediul creat de serverul de aplicaţii. Cu alte cuvinte, principiul ``write once, run anywhere'' este valabil şi în privinţa aplicaţiilor Java EE, în sensul că orice aplicaţie care este scrisă în conformitate cu standardul trebuie să funcţioneze la fel de bine pe Oracle WebLogic, IBM WebSphere, Sun GlassFish, etc. (Am enumerat cele mai cunoscute servere de aplicaţii de astăzi.)

Arhitectura sistemelor dezvoltate în tehnologia discutată aici este dezvoltată pe trei niveluri: client, server de aplicaţii, baza de date, şi reprezintă o evoluţie a arhitecturilor mai vechi, de tip client-server. Având în vedere că în interiorul serverului de aplicaţii există două containere, unul care administrează componente Web(pagini JSP şi JSF), altul care administrează componente de tip EJB (Enterprise JavaBeans), aplicaţia are în general chiar patru niveluri: client(browser de Web), container Web (pagini JSF sau JSP), container de componente EJB, baza de date.