Monday, March 20, 2006

Java UK06

It was great to be there but in general, nothing new. The upcoming trends are well known:
  • EJB 3
  • JSF
  • JAXB
  • AJAX
    It means - everyone should pay attention to this topic if wants to be part of the main-stream.
    What surprised me at most was a fact, that the SOA seems to be dead. You probably remember the hype around SOA but when it comes to reality, there is a silence of the lambs ...
    Just a small example: at Java UK06 there was a track 3 and track 4. Track three objectives concerned the JSF and AJAX and took place at middle-size side-room. Track four was about SOA and took place at the main conference hall. And while track three was literally overcrowded, there were just about 10 people who waited for an SOA experience. And when I looked to the empty hall I spoke to myself - SOA is dead ...
  • Tuesday, March 14, 2006

    Java UK06 London

    I'm going to visit Java UK06 today. It will be my first pure java community experience and I just can't wait :-) I hope I'll find some of Glassfish guys out there. Anyway, the program looks pretty good (check it out). I'm interested especially in Java EE 5, but I'll certainly take on look on some SOA stuff (just because of the hype around)and Web development (it will be mostly about JSF however it is good to know my enemy :-))
    Finally, I'll be back on Thursday and I'll definitely write an article on my trip to London Java UK06

    Sunday, March 12, 2006

    Progress information

    Weekend is gone so here's the current status of my EJB3 vs. Wicket effort:
    Work on all parts is in progress ie. database is running, ejb tier basically works, wicker layer is working. More in-depth view on all technologies involved
  • Database: tables are ready and database generation script done as well.
  • EJB: persitent beans are finished, other beans basically works but there is still a lot of work ahead. Skeleton of webservice, which is just an interface between session beans and logic hidden behind, is completed.
  • Wicket: web layer is working too. Most of the panels are unfinished so the application could be rather called a torso application, however the main idea is already apparent.
    You can download tarball of the application from here and here. Note that required libraries (axis and wicket) are not supplied !
  • Saturday, March 11, 2006

    The easiest way to create a webservice in EJB3

    As you certainly already know, webservoces rules the world. You can call them from almost anywehere means any platform, any technology. To create a webservice in the world of EJB2.1 and related technologies used to be a tough task. The upcoming EJB3 is changing a lot in this area. From the developer's point of view, the main change is that to create a webservice he/she doesn't need to be a guru. For demostration purpose I've created a tiny Webservice. Actually it doesn't do anything useful just calls to underlaying EJB.
    The very basic principle of creation of webservice is to develop class that is an EJB (stateless or stateful) and mark it as a webservice. It means annotate class as @Stateless and @WebService. If you do that, you've got a webservice but unfortunetaly without any accessible method. To publish a method as a web method simply annotate a method with @WebMethod annotation. And here is the example of WebService:
    package org.defectus.ejb3.ws;

    import javax.ejb.Stateless;
    import javax.jws.WebMethod;
    import javax.jws.WebService;

    @Stateless
    @WebService(serviceName = "ResultService")
    public class Service {

    @WebMethod(operationName="TestResult")
    public long testResult (long id {
    return id;
    }

    @WebMethod(operationName="StringResult")
    public String stringResult (String id) {
    if (id == null)
    return "null";
    return id;
    }
    }
    The next step is to deploy such webservice. It should be an easy thing but for me it's not like that. I don't know why but to successfuly deploy webservice I have to call WSGEN manually. Manually in my particular case means to call an ant's task. For example like this:
    <target name="generate-wsdl" depends="compile-ejb">
    <mkdir dir="${build.dir}/generated/wsdl" />
    <mkdir dir="${build.dir}/service" />
    <exec executable="${appserver.dir}/bin/wsgen" failonerror="true">
    <arg line="-extension -cp ${build.dir} -d ${build.dir} -r ${build.dir}/generated/wsdl -wsdl org.defectus.ejb3.papp.ws.ResultService" />
    </exec>
    </target>

    After you deploy the webservice don't forget to use a nice feature of glassfish - webservice tester. Just locate the webservice in administration console adn click the Test button.
    And that's all for now. I'll try to find another feature to explain latter ...

    Thursday, March 09, 2006

    Several of links to opensource friendly corporate sites

    Logica
    IBM
    Thoughtworks
    I'll find more but these are good example of how even big corporations participate on open source and community initiative.

    Tuesday, March 07, 2006

    EJB3 and Wicket

    It's been a long time I posted something new to the blog you're reading and now it's finaly time to write about my progress on a technology field.
    First of all - my EJB 3.0 example in this blog was mentioned in official Glassfish blog. I was really surprised ! And I will proudly work hard to make a lot of new achievements that can be displayed on a frontpage of some well respected blogs.
    In EJB3 is still water mow - nothing revolutional is going on - everyone work hard to stabilized source code. I don't have any information that in near future there will be same major changes in specification and/or implementation of EJB 3.0. For myself I have to say I'm working on a new project - it would be some kind of time-tracker or something like that - I'm not sure if I will be able to finish this work but hopefuly I will ... If not, there will be another torso of example application .-)
    With Wicket I have no progress and it makes me unhappy. Wicket team have just announced version 1.2 beta so it's good time to restart my attempt to create something meaningful using the framework. Here is my idea (vision) from the used technologies point of view:
    Database is Oracle, actually without any logic in PL/SQL (would be added latter but it requires some kind of mapping tool - iBatis could fit my needs)
    Logic will be encapsulated in Glassfish. EJB3 persistence will handle database layer (there would be a number of native query as I really like SQL), above it will be a number of stateless beans acting as facade and even higher will be a webservice managing all the stuff.
    The client side would be done in Wicket. This application will run on Tomcat and using Apache Axis it will call Glassfish backend.
    Right now I have a database model, persitence layer without queries, sample facade bean and sample webservice. I also have a skeleton of Wicket app - means build.xml.
    In upcoming weeks I expect a significant progress because after that I have to prepare myself to another certification - and that costs time and huge amount of brain energy .-)

    Wednesday, March 01, 2006

    Don't use resource injection for anything stateful in Java EE 5 !

    EJB3 has an impressive feature - a resource injection. You can mark class attribute by annottation @Resource or @EJB and application server will inject requested resource at runtime. So far so good, but imagine servlet that uses stateful EJB. When you run this servlet in single-threaded model then there is only one instance of servlet with only one injected resource - so as the result, everyone who calls the servlet uses just one stateful bean ! And mostly, this is not what you want allow, mostly you want bind one servlet session to one stateful bean. The same trouble is for example with @PersistenceProvider. However in this case things are even complicated - your application should run smoothly but from time to time you'll experience serious troubles concerns threading and transactions. This is a side effect of fact that @PersitanceManager is not thread safe and can't manage multiply transactions.
    Do you want to know more ? Click here !

    Monday, February 20, 2006

    Way for SJCP certification

    There're many people trying to prepare themself for the SCJP. That's a good idea to put yourself to the test although the problem is where to find resources. If you've decided to make (and even pass) SCJP 5 you'll find that there is only limited number of mock exams, user experience and so on.
    For this purpose here is my list of sites, tools and tutorials which are worth to take or just explore. Remember - every mock test you pass, everything you try to program, everything what you read - it counts ! Finally bear in mind - reading is NOT enough - you need hands on experience as most of the questions troubleshoot java code.
    SCJP 5 is dedicated to Java 5 and basically is more defficult then SCJP 1.4.
    First step you definitely must take is visiting Sun's Java certification site. Read carefully certification objectives and try to prepare only for objectives mentioned there - stay focused on a target and everything will be all right !
    Next, read this PDF - it contains a lot of useful information on the test - but until you feel you're ready don't complete questions. Save them for last week before assesment and be noticed that many of questions indicates wrong number if correct answers so it's better to find correct answer by compiling given code.
    There is a list of useful links to many mock exams on Javaranch Almost all of them are very easy even if their authors claim them to be tough !
    A huge community is around Java black belt site. Worth to take some question specifically some from SCJP section. Note that these question are mantained by volunteer so the quality of questions (except for my question) differ from one another !
    It's good to take some questions at Examulator. After your correct answer on question of the day, you can take comprehensive test of 60 more questions. But they're quite easy ...
    And that's all folks. If you want to score high and willing to spend some money ($59) download exam simulator from Whizlab. Many questions are buggy but the difficulty level is very close to the real test ! It's good to make at least 80%.
    So, let's get certified :-)

    I'm certified :-)

    At last, I'm certified. It took me almost two months, lot of dreamless nights, weekends in front of computer etc. but finally it paid off. And what to do next ? On friday I'll give a presetantion on Java EE 5 (specificaly EJB3 and beyond).
    And my next challanges ?
    1)Wicket - as I said before, I really like it and want to get more and more from this fantastic framework.
    2)OCA - I'd like to achieve Oracle certified associate. Hopefuly I'll be certified in three to four months (at june/july).
    For now on - there is Java EE 5 and then Wicket. Means lot of work and no time for boring :-)

    Tuesday, February 14, 2006

    Now I'm running 80% ! And more on my progress with Wicket ...

    Yes, it's been a week you don't listen from me. But now the waiting is over .-) I'm still prepering for SJCP5 certification test and as a sideeffect I've recently gained Java yellow belt - After all the misery with Whizlab's test suite I'm passing on roughly 80 % - it could quarantee 90% at real tests, but who knows. I know, I have my weaknesses though hopefully I'll pass the test. Anyway, the JavaBlackBelt initiative is quite impressive - check it out at http://www.javablackbelt.org/! I'm sure you'll find many interesting issues you don't even know about Java language !
    Now for the Wicket framework. It's really what I want. I'm definitely surprised - those guys doing things the way I would do. Of course - to learn a new framerk as Wicket is painful and means to spend a lot of night sleepless but the result is fantastic. I'll keep on learning and I'll surely post some code snippets from my application. If you want to know more on Wicket proceed here.
    So enough for today, I'll keep the rest for tomorrow :-)

    Friday, February 10, 2006

    Still running on 50 %

    Mock test. These from Whizlab are tough one. I don't know why, but I can pass any test, but this. The questeions are difficult and what's more - they're artificialy difficult. Most of the questions are poorly formated so even to recognize code take a lot of time. That's why I hate them and why I hope that the real question will be better to understand and if they will even harder then the hardnest will be managed by clearer approach - no fog over the code. For example take a look at this snippet:


    interface Counter {
    private int countToFive ()
    {
    int a;
    for (a = 1;a<5;a++)
    System.out.printf("counting" + a);
    }

    }
    class Beta
    {
    public static void main (String ... args)
    Counter c = new Counter () {
    public countToFive () {
    for (int a = 0;a<6;a++)
    System.out.printf("counting" + a);
    }
    }; c.countToFive();
    }}
    What a mess !

    Tuesday, February 07, 2006

    Preparing for certification

    Sometimes you may consider yourself as a good programmer. So as I. And that was the reason why I have desided to put myself to the test. But after three crucial weeks of preparation I realize how hard is to answer all the qestions. of course, I'm using mock question from all over the globe (mostly located on JavaRanch) and for "close to reality" or even "harder then reality" I'm using mock question provided by Whizlab. Thay give a 150% pass certification garantee - it's only trick. When you ask people "god like difficult" question you can be sure, that those who will pass the test for them the real test will be a child game :-) Now I know my weaknesses (generics, formatters & scanners, exceptions) and I'm learning. And I'll be ready for test two weeks later hopefully ... :-) Till that - good bye Wicket, bye bye EJB3 !

    Tuesday, January 31, 2006

    Unexpected side-effect

    Learning to new features of Java 5 I've discovered new way to call the main method. I know, I'm not first but it's nice to see things in consequences. From now on I'll abandon good but old
     static void main (String [] args) {...}
    I'll start to use
    static void main (String ... args){...}
    instead. It's a sing of a new era established by Java 5 ...

    Project management ...

    It's like I can see at out company. When we start to do out business we were a small firm ran by 3 so-called managers and the rest was a group of developers. These days, we have 4 level executive system :-( I'm directed by number of people which I don't know personally ...
    LFO's Weblog

    Axis rules ! :-)

    Yesterday evening (as I always do what I like to on evenings and weekdns) I for a first time met Apache Axis. And I was really pleased by it. It's definitely the library as library should be. Well documented, supplied with all necessary binding (such as to ant, to log4j, to junit ...), so to establish connection to the webservice took me just a several minutes. And I've been poorly exapecting hours :-) Well, thank you very much Apache guys !!!

    Monday, January 30, 2006

    Put it to the test :-)

    Question:
    12. Which of the following may legally appear as the new type (between the parentheses) in a cast
    operation?
    A. Abstract classes
    B. Final classes
    C. Primitives
    D. All of the above
    Answer:
    12. E. Any type, including classes with any kind of modifier, may appear inside the parentheses
    of a cast.

    And I was wrong again, because I overlooked the E choice :-)))

    Eclipse java compilation ?!

    I found something strange conrens Eclipse. The point is, that Eclipse compile even invalid java code - and, somehow runnable. Take a look on these source files:


    package test;

    public interface IntA {
    void A();
    void B();
    void C();
    void D();
    void E();
    }


    package test;

    public class ClsB implements IntA{

    public void A() {
    System.out.println("A");
    }
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    System.out.println("Howdyyyy");
    IntA a = new ClsB();
    a.A();
    // a.B(); when uncommented, class doesn't compile
    }

    }

    All right. This class would be compilable even when is marked as "abstract". So, any attempt to compile with javac results to:


    K:\UFO_G3\workspace\test>c:\jdk5\bin\javac.exe test/*.java
    test/ClsB.java:3: test.ClsB is not abstract and does not override abstract metho
    d E() in test.IntA
    public class ClsB implements IntA{
    ^
    1 error

    as expected. But when in Eclipse, everything is OK but you can't even run such class with this result:

    Nebylo možno načíst třídu prostředí Java: java.lang.UnsupportedClassVersionError: test/ClsB (Unsupported major.minor version 49.0)
    And I'm asking: why is possible to compile an invalid class ? Why Eclipse using some internal compiler with a non-standard results ? Perhaps that's the reason why I'm using eclipse only as an editor and compiling classes with the Ant ...

    Troubles with Wicket vs. Glassfish

    Weekend is gone and here is a resultsheet of my work, study, tests, workarounds etc.
    First of all - Java 6 Mustang has limited backward compatibility. I can't say more on this right now, but based on my experiments, it can't work with Java 1.3 classes. That's quite surprising ! I'll try to get more on the subject.
    I didn't succeed to improve performance of the EJB with complex mapping. Persistence provider is still loading whole database with a sign of some kind of recursion when I'm trying to get just entity of one type (for example an employee). I've tried almost everything ! Bad luck though ...
    All right, the next task was preparation for the certification. I've accomplished 3 chapters (out of 15 total) and my test ratio is cca. 90%. That's OK as required ratio is appriximately 60%. But what I hate about the certification test are questions like - given interface A with five methods and class B that claims to implement interface A but actually isn't implementing any method, what will be result of compilation attempt. a) the class will not be compiled b) ... c) ... d) class will be compiled but can't be instantioned e)class will be abstract. And correct answer is d) and e). But why ?! On Java 5 this example works and class is even runnable (as long as you don't call methods inherited from the interface). On JDK 4 it fails to compile at all. So what is conclusion ?!
    Wicket - Wicket is excelent. So for I like it very match, but for reason unknown Wicket is in collision with Glassfish. When I deploy my Wicket application onto the Glassfish for a fiveth time Glassfish crash with strange message like "PrmGen" out of memory ... Anyway, Glassfish has a serious problem with webservices. Webservice with method that returns not elemental objects (not Strings, Lists ...) cause Glassfish to crash or if I'm lucky it just cause weird behaviour of the Glassfish ... Nobody knows why and I don't mind to find it. So I'll go to the Tomcat. Tomcat is a proven server so maybe, I'll be more lucky with this one.

    Friday, January 27, 2006

    On EJB3 again

    So, recently I have posted the whole test project on my website. It is now available through this link so you can grab it if you want. This piece of code is designed to run on GlassFish build 34 and as a backend database it uses Oracle XE with HR scheme enabled.
    Yesterday evening I successfuly overode annotations by xml descriptors so now I know how to do it. This is not a magic - just use your EJB 2.1 style descriptors and everything will be just fine. For more see example of EJB3Servlet - there is a call to fooQeueue that is actuelly mapped to testQueue.
    What is now bear in my mind is perfomance of entity beans - it's back to the root problem because I didn't solve it yet and this problem occured in the begging of my work. I hope the persitence layer is somehow "confused" by so many circular mappings. I'll try to eliminate some of them (for example mappimg emloyee-manager department-manager and so on) and hope it helps.
    Last week I found a great community of same thinking people around EJB3 at glassfish forum. They helped me to solve my initial problem with message driven bean (the problem when I forgot to implement MessageListener interface). Yesterday I posted there another problem and hopfuly they'll help to find some solution. It's about NativeNamedQuery but you better see for yourself here.
    I don't know exactly what I'm goind to do next but I'll choose from these:
  • As part my certification preparation, improve example application by adding more features of Java 5.
  • Add Wicket support (even without any Java 5 or EJB3 feature) just to get familiar with this powerful framework
  • Try out Caché database. This "post relational" database has many uniques - it doesn't require object-relational mapping as data are stored as objects ! It would be fun :-)
    As you can see, I have a lot of challenges ahead ... And no time to waste :-)
  • Wednesday, January 25, 2006

    MDB problem solved - I'm moving for another challenge

    it maybe sounds like I'm talking only about my EJB3 presentation (what is almost truth :-)) but now I solved last crucial problem - message driven bean works for now, so I can stick myself for another. The last thing I want to show is NamedNativeQuery and then - hasta la vista EJB 3 - I will continue working to explore some new feature of Java 6 (Mustang) and I'll go for certification. If you'e curious what was the problem, well, it was really tricky byt definitely it was my fault. I forgot to implement MessageListenetr interface and every message driven bean must implement such interface. I read the documentation only once and very briefly so I overlooked the sentence that message driven bean should be annotated as @MessageDriven and should implement MessageListener interface too. Next time I'll be reading documentation carefully ...

    Monday, January 23, 2006

    Examples strike back :-)

    Ok, here we go. First of all, prerequisition:

  • EJB3 container (glassfish is used in this scenario)
  • Database (Oracle XE with activated HR scheme)
  • Ant
  • A lot of time :-)
    If you've downloaded all the software required, you can move on to second stage. First of all let's create entity beans. These're plain old java objects (POJO) with some annotations. I've created two version. One that contain full annotation, including relationships and the second one (with prefix Bare) that is relationshipless. Here is snapshot of class Employees with full links to other tables:

    package org.defectus.ejb3.ic2.entity.complex;

    import java.io.Serializable;
    import java.util.Collection;

    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.ManyToOne;
    import javax.persistence.NamedQuery;
    import javax.persistence.OneToMany;
    import javax.persistence.Table;

    @Entity
    @Table(name = "EMPLOYEES")
    @NamedQuery(name = "selectAllEmps", query = "select object(o) from Employees o")
    public class Employees implements Serializable {
    private static final long serialVersionUID = 1987305452306161213L;

    private Double commissionPct;

    private String email;

    private Long employeeId;

    private String firstName;

    private String lastName;

    private String phoneNumber;

    private Double salary;

    private Departments department;

    private Employees manager;

    private Collection employees;

    private Jobs jobs;

    private Collection departments;

    public Employees() {
    }

    public Employees(String email, Long employeeId, Jobs jobs, String lastName) {
    this.email = email;
    this.employeeId = employeeId;
    this.jobs = jobs;
    this.lastName = lastName;
    }

    @Column(name = "COMMISSION_PCT")
    public Double getCommissionPct() {
    return commissionPct;
    }

    public void setCommissionPct(Double commissionPct) {
    this.commissionPct = commissionPct;
    }

    @Column(name = "EMAIL", nullable = false)
    public String getEmail() {
    return email;
    }

    public void setEmail(String email) {
    this.email = email;
    }

    @Id()
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "EMPLOYEES_SEQ")
    @Column(name = "EMPLOYEE_ID", nullable = false)
    public Long getEmployeeId() {
    return employeeId;
    }

    public void setEmployeeId(Long employeeId) {
    this.employeeId = employeeId;
    }

    @Column(name = "FIRST_NAME")
    public String getFirstName() {
    return firstName;
    }

    public void setFirstName(String firstName) {
    this.firstName = firstName;
    }

    @Column(name = "LAST_NAME", nullable = false)
    public String getLastName() {
    return lastName;
    }

    public void setLastName(String lastName) {
    this.lastName = lastName;
    }

    @Column(name = "PHONE_NUMBER")
    public String getPhoneNumber() {
    return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
    this.phoneNumber = phoneNumber;
    }

    @Column(name = "SALARY")
    public Double getSalary() {
    return salary;
    }

    public void setSalary(Double salary) {
    this.salary = salary;
    }

    @ManyToOne()
    @JoinColumn(name = "DEPARTMENT_ID", referencedColumnName = "DEPARTMENTS.DEPARTMENT_ID")
    public Departments getDepartment() {
    return department;
    }

    public void setDepartment(Departments departments) {
    this.department = departments;
    }

    @ManyToOne()
    @JoinColumn(name = "MANAGER_ID", referencedColumnName = "EMPLOYEES.EMPLOYEE_ID")
    public Employees getManager() {
    return manager;
    }

    public void setManager(Employees manager) {
    this.manager = manager;
    }

    @OneToMany()
    public Collection getEmployees() {
    return employees;
    }

    public void setEmployees(Collection employees) {
    this.employees = employees;
    }

    public Employees addToEmployeesCollection(Employees employees) {
    getEmployees().add(employees);
    employees.setManager(this);
    return employees;
    }

    public Employees removeFromEmployeesCollection(Employees employees) {
    getEmployees().remove(employees);
    employees.setEmployees(null);
    return employees;
    }

    @ManyToOne()
    @JoinColumn(name = "JOB_ID", referencedColumnName = "JOBS.JOB_ID")
    public Jobs getJobs() {
    return jobs;
    }

    public void setJobs(Jobs jobs) {
    this.jobs = jobs;
    }

    @OneToMany()
    public Collection getDepartments() {
    return departments;
    }

    public void setDepartments(Collection departments) {
    this.departments = departments;
    }

    public Departments addToDepartmentsCollection(Departments departments) {
    getDepartments().add(departments);
    departments.setManager(this);
    return departments;
    }

    public Departments removeFromDepartmentsCollection(Departments departments) {
    getDepartments().remove(departments);
    departments.setManager(null);
    return departments;
    }
    }
    As you can see, it's very straightward - nothing is hidden and, there is no logic ! No methods, except for constructor. But if you take a closer look on OneToMany mapping you can realize that there must be some kind of executive code out there. And it certainly is. Entity manager hides further logic behind the Collection of Departments. This logic is responsible for lazy fetching of Departments. As long as you run this code inside the container (ie. Glassfish) everything is all right but once you try to send such POJO over let's say webservice you can encounter a serious problem. As far as I'm aware there's no way how to detach such POJO and attached POJO can't be detached by SOAP message creator. And that's the reason why I have created second version of EJBs. In the next example you'll see the same table (Employees) but without any relationship included:

    package org.defectus.ejb3.ic2.entity.bare;

    import java.io.Serializable;

    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.EntityResult;
    import javax.persistence.FieldResult;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.NamedNativeQuery;
    import javax.persistence.NamedQuery;
    import javax.persistence.SqlResultSetMapping;
    import javax.persistence.Table;

    @Entity
    @Table(name = "EMPLOYEES")
    @NamedQuery(name = "selectAllEmps", query = "select object(o) from Employees o")
    @NamedNativeQuery(name = "selectNativeEmps", query = "SELECT EMPLOYEE_ID, FIRST_NAME, LAST_NAME, SALARY FROM EMPLOYEES WHERE EMPLOYEE_ID = ?", resultSetMapping = "employeeNamedMapping", resultClass=org.defectus.ejb3.ic2.entity.bare.BareEmployees.class)
    @SqlResultSetMapping(name = "employeeNamedMapping", entities = { @EntityResult(entityClass = org.defectus.ejb3.ic2.entity.bare.BareEmployees.class, fields = {
    @FieldResult(name = "employeeId", column = "EMPLOYEE_ID"), @FieldResult(name = "firstName", column = "FIRST_NAME"),
    @FieldResult(name = "lastName", column = "LAST_NAME"), @FieldResult(name = "salary", column = "SALARY") }) /*, discriminatorColumn="disc")*/})
    public class BareEmployees implements Serializable {
    private static final long serialVersionUID = 1987305452306161213L;

    private Double commissionPct;

    private String email;

    private Long employeeId;

    private String firstName;


    private String lastName;

    private String phoneNumber;

    private Double salary;

    private Long departments;

    private Long employees;

    private String jobs;

    public BareEmployees() {
    }

    public BareEmployees(String email, Long employeeId, String jobs, String lastName) {
    this.email = email;
    this.employeeId = employeeId;
    this.jobs = jobs;
    this.lastName = lastName;
    }

    @Column(name = "COMMISSION_PCT")
    public Double getCommissionPct() {
    return commissionPct;
    }

    public void setCommissionPct(Double commissionPct) {
    this.commissionPct = commissionPct;
    }

    @Column(name = "EMAIL", nullable = false)
    public String getEmail() {
    return email;
    }

    public void setEmail(String email) {
    this.email = email;
    }

    @Id()
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "EMPLOYEES_SEQ")
    @Column(name = "EMPLOYEE_ID", nullable = false)
    public Long getEmployeeId() {
    return employeeId;
    }

    public void setEmployeeId(Long employeeId) {
    this.employeeId = employeeId;
    }

    @Column(name = "FIRST_NAME")
    public String getFirstName() {
    return firstName;
    }

    public void setFirstName(String firstName) {
    this.firstName = firstName;
    }

    @Column(name = "LAST_NAME", nullable = false)
    public String getLastName() {
    return lastName;
    }

    public void setLastName(String lastName) {
    this.lastName = lastName;
    }

    @Column(name = "PHONE_NUMBER")
    public String getPhoneNumber() {
    return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
    this.phoneNumber = phoneNumber;
    }

    @Column(name = "SALARY")
    public Double getSalary() {
    return salary;
    }

    public void setSalary(Double salary) {
    this.salary = salary;
    }

    @Column(name = "DEPARTMENT_ID")
    public Long getDepartments() {
    return departments;
    }

    public void setDepartments(Long departments) {
    this.departments = departments;
    }

    @Column(name = "MANAGER_ID")
    public Long getEmployees() {
    return employees;
    }

    public void setEmployees(Long employees) {
    this.employees = employees;
    }

    @Column(name = "EMPLOYEES.JOB_ID")
    public String getJobs() {
    return jobs;
    }

    public void setJobs(String jobs) {
    this.jobs = jobs;
    }
    }
    In this example you perhaps lack the relationship annotations and structures but a native query has been add. Note that EJB3 easily fall to annotation defaulting. This means that even if you omit annotate class field as Column deployer will find that in related table is matching column and will bind tthe column and the filed together.
    And now for something completely different :-) Let's take look on a facade class. Its purpose is to create an interface and cover all the logic behind. There're some important things you should be noticed about. Class is annotated as Stateless - it means that class is stateless session bean. Also, class has interceptor. This feature will be discussed later. In a body of the class is something called EntityManager annotated with @PersistenceContext. It indicates that class uses persistence and container should inject EntityManager to given attribute. Note that this way of instructing container to inject EntityManager is not the only one way how to do it and the other ways are perhaps even better (consider for example usage of EntityManagerFactory). pu1 specified which persitence context should be used. Later in the code you'll see some methods, which, as I hope, should be easy to understand.

    package org.defectus.ejb3.ic2.session;

    import java.sql.Timestamp;
    import java.util.Date;
    import java.util.List;

    import javax.ejb.Interceptors;
    import javax.ejb.Stateless;
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;

    import org.defectus.ejb3.ic2.entity.bare.BareDepartments;
    import org.defectus.ejb3.ic2.entity.bare.BareEmployees;
    import org.defectus.ejb3.ic2.entity.bare.BareJobs;
    import org.defectus.ejb3.ic2.entity.bare.BareLogs;
    import org.defectus.ejb3.ic2.entity.complex.Departments;
    import org.defectus.ejb3.ic2.entity.complex.Employees;
    import org.defectus.ejb3.ic2.entity.complex.Locations;

    @Stateless (mappedName="ejb/DataFacade")
    @Interceptors( { org.defectus.ejb3.ic2.session.DataInterceptor.class })
    public class DataFacadeBean implements DataFacade {
    @PersistenceContext(unitName = "pu1")
    private EntityManager _entityManager;

    public DataFacadeBean() {
    }

    public EntityManager getEntityManager() {
    return _entityManager;
    }

    public void setEntityManager(EntityManager entityManager) {
    _entityManager = entityManager;
    }

    public List findDept(String name) {
    @SuppressWarnings(value = { "unchecked" })
    List deps = getEntityManager().createQuery(
    "select object(o) from Departments o where o.departmentName=:name").setParameter("name", name).getResultList();
    return deps;
    }

    public List findAllDept() {
    @SuppressWarnings(value = { "unchecked" })
    List deps = getEntityManager().createQuery("select object(o) from Departments o").getResultList();
    return deps;
    }

    public Departments createDepartment(String departmentName, Long locationId) {
    final Departments dept = new Departments(departmentName);
    Locations location = getEntityManager().find(Locations.class, locationId);
    dept.setLocation(location);
    getEntityManager().persist(dept);
    return dept;
    }

    public BareLogs createLog(String message) {
    final BareLogs log = new BareLogs(message, new Date());
    getEntityManager().persist(log);
    return log;
    }

    public List findAllComplexEmployees() {
    @SuppressWarnings(value = { "unchecked" })
    List emps = getEntityManager().createNamedQuery("selectAllEmps").getResultList();
    return emps;
    }

    public List findAllBareEmployees() {
    @SuppressWarnings(value = { "unchecked" })
    List emps = getEntityManager().createQuery("select object(o) from BareEmployees o").getResultList();
    return emps;
    }

    public List findBareEmployees2() {
    @SuppressWarnings(value = { "unchecked" })
    List emp = getEntityManager().createNamedQuery("selectNativeEmps").setParameter(1,101).getResultList();
    return emp;
    }

    public BareJobs findBareJobs(String jobId) {
    return getEntityManager().find(BareJobs.class, jobId);
    }

    public BareEmployees findBareEmployee(Long emplId) {
    return getEntityManager().find(BareEmployees.class, emplId);
    }

    public BareDepartments findBareDepartment(Long depId) {
    return getEntityManager().find(BareDepartments.class, depId);
    }

    public List findAllDepartments() {
    @SuppressWarnings(value = { "unchecked" })
    List deps = getEntityManager().createNamedQuery("selectAllDeps").getResultList();
    return deps;
    }

    public Employees createEmployee(Double comm, Long deptno, String email, String firstName, String lastName,
    Timestamp hiredate, String job, Double sal) {
    final Employees emp = new Employees();
    Departments dep = getEntityManager().find(Departments.class, deptno);
    emp.setCommissionPct(comm);
    emp.setDepartment(dep);
    emp.setEmail(email);
    emp.setFirstName(firstName);
    emp.setLastName(lastName);
    emp.setSalary(sal);
    getEntityManager().persist(emp);
    return emp;
    }

    public void updateEntity(Object entity) {
    getEntityManager().merge(entity);
    }

    public void deleteEntity(Object entity) {
    final EntityManager em = getEntityManager();
    em.remove(em.merge(entity)); // interesting way how to delete entity of any type
    }

    public void refreshEntity(Object entity) {
    getEntityManager().refresh(entity);
    }

    public void shutdown() {
    getEntityManager().close();
    }


    }
    For the bean a remote interface is needed. To create one you have to annotate appropriate interface as @Remote and make the class above implement such interface. Note that the interface can be Remote, Local but can't be both.

    package org.defectus.ejb3.ic2.session;

    import java.sql.Timestamp;
    import java.util.List;

    import javax.ejb.Remote;
    import javax.persistence.EntityManager;

    import org.defectus.ejb3.ic2.entity.bare.BareEmployees;
    import org.defectus.ejb3.ic2.entity.bare.BareJobs;
    import org.defectus.ejb3.ic2.entity.bare.BareLogs;
    import org.defectus.ejb3.ic2.entity.complex.Departments;
    import org.defectus.ejb3.ic2.entity.complex.Employees;

    @Remote
    public interface DataFacade {

    public abstract EntityManager getEntityManager();

    public abstract void setEntityManager(EntityManager entityManager);

    public abstract List findAllDept();

    public abstract List findDept(String name);

    public abstract Departments createDepartment(String departmentName, Long locationId);

    public abstract BareLogs createLog(String message);

    public abstract List findAllBareEmployees();

    public abstract BareJobs findBareJobs(String jobId);

    public abstract BareEmployees findBareEmployee(Long emplId);

    public abstract List findAllComplexEmployees();

    public abstract List findAllDepartments();

    public abstract Employees createEmployee(Double comm, Long deptno, String email, String firstName, String lastName,
    Timestamp hiredate, String job, Double sal);

    public abstract void updateEntity(Object entity);

    public abstract void deleteEntity(Object entity);

    public abstract void refreshEntity(Object entity);

    public abstract void shutdown();

    }
    Interceptor is something that is called before any particular call to method of intercepted bean. From the code below it's easy to understand the way of interception

    package org.defectus.ejb3.ic2.session;

    import javax.ejb.AroundInvoke;
    import javax.ejb.InvocationContext;

    import org.defectus.ejb3.ic2.entity.bare.BareEmployees;

    public class DataInterceptor {

    @AroundInvoke()
    public Object myBeanInterceptor(InvocationContext ctx) throws Exception {
    if (ctx.getMethod().getName().equals("findDept")) {
    String name = (String) ctx.getParameters()[0];
    Object[] o = new Object[1];
    o[0] = name;
    ctx.setParameters(o);
    } else if (ctx.getMethod().getName().equals("findBareEmployee")) {
    Long id = (Long) ctx.getParameters()[0];
    if (id.longValue() == 888)
    return new BareEmployees(null, null, null, "Who wants to know ? :-)");
    }
    return ctx.proceed();
    }
    }
    The second IF is interesting - because it interrupts call to underlaying method so the method is actually not called at all ! This means - when you ask the bean for employee 888 interceptor returns one without even calling datafacade bean. Very nice. Note that specification have changed and Intercaption resides in different package (but it works the same way as before).In the next class you'll see is a servlet that acts as data provider to AJAX page. Although servlets are not annotated (you must provide valid web.xml) you can use annotations though. Annotation @EJB instructs server to inject reference to EJB. The rest of the class is servlet as usual. Just for your information, the last Java EE 5 specification prohibit usage of stateful bean in servlets.

    package org.defectus.ejb3.ic2.ws;

    import java.io.IOException;
    import java.util.Map;

    import javax.ejb.EJB;
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import org.defectus.ejb3.ic2.entity.bare.BareEmployees;
    import org.defectus.ejb3.ic2.session.DataFacade;

    public class DataProvider extends HttpServlet {
    private static final long serialVersionUID = -7542313195870441831L;

    @EJB(name = "org.defectus.ejb3.ic2.session.DataFacade")
    private DataFacade data;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
    ServletOutputStream o = res.getOutputStream();
    res.setContentType("text/xml");
    res.setCharacterEncoding("utf-8");
    String action = null;
    Long id = null;
    try {
    action = req.getParameter("action");
    } catch (Exception e) {
    o.println("");
    o.println("");
    o.println("
    Invalid request !!! No action provided
    ");
    o.println("
    ");
    o.println("
    ");
    o.flush();
    o.close();
    return;
    }
    Map params = req.getParameterMap();
    if (action.equals("singleEmployee")) {
    printSingleEmployee(o, Long.getLong((String) params.get("id")));
    } else if (action.equals("employeeList")) {
    printEmployeeList(o);
    }
    }

    private void printSingleEmployee(ServletOutputStream o, Long value) throws IOException {
    o.println("");
    o.println("");
    o.println("
    " + data.findBareEmployee(value).getLastName() + "
    ");
    o.println("
    ");
    o.println("
    ");
    o.flush();
    o.close();
    }

    private void printEmployeeList(ServletOutputStream o) throws IOException {
    o.println("");
    o.println("");
    o.println("");
    o.println("
    ");
    o.println("
    ");
    o.flush();
    o.close();
    }
    }
    And that's all for now. I'll continue later and try to cover another techniques related to EJB 3.
  • Thursday, January 19, 2006

    Examples

    It maybe looks like don't keep my faith and I want to change it. I promised to put here some examples and I'll finally do. So tonight, you can expect some covering basic practices of EJB3. At least because right now I just playning with AJAX.
    My next task ? To get a Java 5 certification. Just another 2 tough months.

    Wednesday, January 18, 2006

    Breaking the ice

    So far so good. Yesterday I've finished my persistance comparison with interesting result. To get all employees took 13 seconds using complex O-R mapping with EJB3 but only 70 milliseconds using bare mapping (without relations ie. to get employees means to get data from employees table). I don't know what cause such performance degradation yet but I'll try to find out.
    As my second task I've tried interceptors. Pretty feature ! You can intercept any call to EJB (stateless or stateful) and add any functionality to it or supress execution of EJB at all. It's some kind of AOP but without AOP or filter known from servlets. For example at my application I add interceptor which check if you want to get an employee named "Ondra". If so, it will log such attempt and returns an empty Employees object (so one can't get info on me :-))
    Now I'm ready to write data provider servlet - the one which will return data to OpenRico AJAX ... and perhaps continue to fix performance of the complex EJB3 mapped entities.

    Tuesday, January 17, 2006

    Let's do it all over again (for persistance reasons)

    Hmm, it's sad but it's true. Firstly what makes me to rebuild the application. Till midnight everything went very well but then I realized, that performance of my example application is even worse that terrible ! As I mentioned before, I use Oracle's HR database. There are roughly 100 employees, some departmets, some countries etc. but initial load of such application was 20 almost seconds ! So I decided to use lazy fetching. Good idea but annotation @OneToMany(fetch = FetchType.LAZY) is just a suggestion - and for reason unknown, Toplink didn't follow it. I'm just a humble developer so I made up my mind and download latest build of Glassfish - b33 just to try my luck. You can't imagine my surprisal when I wasn't able to compile the project. Toplink has been turned upside-down and many annotation was deleted, renamed or rearranged. More on this here. After all I know what I'll be doing tonight :-)
    It's 1:10 pm and I've made the changes. Piece of cake I must admit. So, @Id no longer contain parameters, @GeneratedValue is newcomer (can be used with every generated field) and everyone is shinny happy. After this small intermezzo I will continue trying to fix the performance issue. All I need to do is to find a balance between code simplicity and application response time.

    Monday, January 16, 2006

    JSF 1.2 doesn't work on Glassfish b31 ?

    It seems to me true. I've tried hard to make it work and accomplish my presentation showing JSF 1.2 but it just doesn't work. Any attempt to call or ahow anything from JSF fails with uknown exception. Even supplied examples fail the same way.
    So I decided to create rich servlet accompanying servlet 2.5 features with some JAXB and on client side uses OpenRico AJAX framework. Perhaps it sounds as tough task, but actually it isn't. Integrations will be very easy as JAXB uses annotations as well as servlet, so everything I will need to do is to annotate my entity classes and add annotation to servlet. And of course, publish several AJAX methods ...
    Anyway, this weekend I even had to deal with camplex EJB3 entity mapping. Project Dali is really buggy (unable to create entity classes) so used JDeveloper 10.1.3. It created entities but ManyToMany mapping is invalid and ManyToOne dosn't conform specification. I didn't solve the first problem but the second one can be easily fixed by editing field annotations to contain only OneToMany (delete the JoinColumn annotation) pointing to referenced class and counterpart class should use JoinColumn annotation together with bare ManyToOne.

    @ManyToOne()
    //targetEntity=org.defectus.ejb3.ic2.entity.Departments.class)
    @JoinColumn(name = "EMPLOYEES.DEPARTMENT_ID", referencedColumnName = "DEPARTMENTS.DEPARTMENT_ID")


    @OneToMany(targetEntity=org.defectus.ejb3.ic2.entity.Employees.class)
    //@JoinColumn(name="EMPLOYEES.DEPARTMENT_ID", referencedColumnName="DEPARTMENTS.DEPARTMENT_ID")
    Hope that is clear - commented parts are these which were generated by JDeveloper but were not valid.

    Saturday, January 14, 2006

    Presentation partly done

    So, my presentation is almost done and can concetrate on examples. I'd like to present complete end to end scenario and show as much of new technoligy, as it will be possible. Perhaps you've seen my previous article and the examples seems to you be some kind of weird. Yes, these examples has been made quite quickly, so the next one will cover more and more of EJB3. I will post here example of ant build file, becasuse deployment is important part of EJB3. During deployment a lot of things take place - but invisibly. Did I mention that you don't need ejb-jar.xml at all ? Cool ! Or you can enjoy benefits of EJB3 persistency outside of application server - ideal for testing.
    Ok, next post will be mostly yellow, as I'm going to post here code of my examples. Hope it helps to anybody ...

    Friday, January 13, 2006

    Presentation - work in progress

    Yesterday I've started to write my presentation concerning EJB3. It covers more then just this - it's about whole Java EE 5 technologies including JAX WS, servlets, JSP, Common annotaton etc. Actually I have six pages and working examples.
    Basically I can say - EJB3 is all about annotations. But annotations are processed by application server or application client so in the end, on background it works similary to EJB 2.1. The main difference is in development point of view. You, as developer, don't need to care whenever you have all interfaces and stub classes, everything is done on deployment. Is very interesting to see what was done with our project after deployment. Just take a closer look to deployment directory and you'll see, that nothing important has changed.
    So stop just talking and watch this example:
    package com.blogspot.deftech.ejb3;
    @javax.ejb.Stateless (name="ejb/foo")
    public class FooBean {
    public String getString (String stringIn) {
    return "You said " + stringIn + " ... Unbelievable !";
    }
    }
    For such class we need an interface - lets create it (nothing complicated)
    package com.blogspot.deftech.ejb3;
    @javax.ejb.Remote
    public interface Foo {
    public String getString (String stringIn);
    }

    As you can see, to create ejb is very very simple. Of course, this one is the simpliest one, but the basic concept is clear. Use annotation and don't care. Everything else will be done by deployer or server itself. In other words - concentrate on business logic, not on support stuff.
    To generate server-side client is easy as one two three :-). Look at this piece of code:
    package com.blogspot.deftech.ejb3;
    public class FooTest {
    @javax.ejb.EJB (name="ejb/foo")
    private Foo fooObject;

    public static void main (String [] args) {
    FooTest test = new FooTest();
    test.run();
    }

    private void run () {
    System.out.println(fooObject.getString ("1+1=2"));
    }
    }
    To deploy such code you need to compile it and pack it into *.jar file. More on this later today. Be patient ...
    Ok this one will not work, but if you make a servlet based on this skeleton, you'll see, how application server literaly injects instance of class Foo to member variable fooObject. There is even another trick like. Let's examine this example:
    package com.blogspot.deftech.ejb3;

    public class ResourceExample {
    javax.sql.DataSource ds = null;

    @Resource(name="jdbc/OracleXE")
    public void setDataSource javax.sql.DataSource value) {
    ds = value;
    }
    }
    In this piece of code application server will inject JNDI resource into setter named setDataSource. Really clean and elegant way how to work with JNDI. No more JNDI lookups, no more narrowing references. But still keep in mind, that on background nothing changes ! The only thing which has changed is that the boring part of work is done by server ... Later I'll post here example of entity beans, which are even more interesting. And also a small example of Web service. But don't expect anything revolutionary - just another set of annotations :-).

    Thursday, January 12, 2006

    Computer technology

    Yes yes yes, it's like that. Technology rules the world and I'm really keen about it. As a java developer I'd like to write my thoughts on this famous language. My technology overview is really wide so I hope, that someone find this blog useful. My first article will cover upcoming Java EE 5 and will by posted soon. Work on thorough examples is done and I'll be glad to post it here ASAP. Till that, happy surfing and I'm looking forward to hearing from you !
    Defectus