Featured FREE Whitepapers

What's New Here?

jboss-hibernate-logo

Hibernate Tip: Sort and Order

Let’s introduce another hibernate performance tip. Do you remember the model of previous hibernate post? We had a starship and officer related with a one to many association.                 @Entity public class Starship {@Id @GeneratedValue(strategy=GenerationType.SEQUENCE) private Long id; public Long getId() {return id;} protected void setId(Long id) {this.id = id;}@OneToMany(mappedBy="starship", cascade={CascadeType.ALL}) private List<Officer> officers = new ArrayList<Officer>(); public List<Officer> getOfficers() {return Collections.unmodifiableList(officers);} protected void setOfficers(List<Officer> officers) {this.officers = officers;} public void addOfficer(Officer officer) { officer.setStarship(this); this.officers.add(officer); }//more code }@Entity public class Officer {@Id @GeneratedValue(strategy=GenerationType.SEQUENCE) private Long id; public Long getId() {return id;} protected void setId(Long id) {this.id = id;}@ManyToOne private Starship starship; public Starship getStarship() {return starship;} protected void setStarship(Starship starship) {this.starship = starship;}//more code }Now we have next requirement: We shall get all officers assigned to a starship by alphabetical order. To solve this requirement we can:implementing an HQL query with order by clause. using sort approach. using order approach.The first solution is good in terms of performance, but implies more work as a developers because we should write a query finding all officers of given starship ordered by name and then create a finder method in DAO layer (in case you are using DAO pattern). Let’s explore the second solution, we could use SortedSet class as association, and make Officer implements Comparable, so Officer has natural order. This solution implies less work than the first one, but requires using @Sort hibernate annotation on association definition.So let’s going to modify previous model to meet our new requirement.Note that there is no equivalent annotation in JPAspecification. First we are going to implement @Entity public class Officer implements Comparable<Officer>{//getters, setters, equals, ... codepublic int compareTo(Officer officer) { return this.name.compareTo(officer.getName()); }}Comparable interface in Officer class. We are ordering officer by name by simply comparing name field. Next step is annotating association with @Sort. @Entity public class Starship {//more code@OneToMany(mappedBy="starship", cascade={CascadeType.ALL}) @Sort(type=SortType.NATURAL) private SortedSet>Officer< officers = new TreeSet>Officer<(); public SortedSet>Officer< getOfficers() {return Collections.unmodifiableSortedSet(officers);} protected void setOfficers(SortedSet>Officer< officers) {this.officers = officers;} public void addOfficer(Officer officer) { officer.setStarship(this); this.officers.add(officer); } }Notice that now officers association is implemented using SortedSet instead of a List . Furthermore we are adding @Sort annotation to relationship, stating that officers should be natural ordered. Before finishing this post we will insist more in @Sort topic, but for now it is sufficient. And finally a method that gets all officers of given starship ordered by name, printing them in log file. EntityManager entityManager = this.entityManagerFactory.createEntityManager(); EntityTransaction transaction = entityManager.getTransaction();transaction.begin(); log.info("Before Find Starship By Id");Starship newStarship = entityManager.find(Starship.class, starshipId); SortedSet<Officer> officers = newStarship.getOfficers(); for (Officer officer : officers) { log.info("Officer name {} with rank {}", officer.getName(), officer.getRank()); } log.info("After Find Starship By Id and Before Commit");transaction.commit(); entityManager.close();All officers are sorted by their names, but let’s examine which queries are sent to RDBMS. Hibernate: select starship0_.id as id1_0_, starship0_.affiliationEnum as affiliat2_1_0_, starship0_.launched as launched1_0_, starship0_.height as height1_0_, starship0_.length as length1_0_, starship0_.power as power1_0_, starship0_.width as width1_0_, starship0_.registry as registry1_0_, starship0_.starshipClassEnum as starship9_1_0_ from Starship starship0_ where starship0_.id=?Hibernate: select officers0_.starship_id as starship7_1_1_, officers0_.id as id1_, officers0_.id as id0_0_, officers0_.affiliationEnum as affiliat2_0_0_, officers0_.homePlanet as homePlanet0_0_, officers0_.name as name0_0_, officers0_.rank as rank0_0_, officers0_.speciesEnum as speciesE6_0_0_, officers0_.starship_id as starship7_0_0_ from Officer officers0_ where officers0_.starship_id=?First query is resulting of calling find method on EntityManager instance finding starship. Because one to many relationships are lazy by default when we call getOfficers method and we access first time to SortedSet, second query is executed to retrieve all officers. See that no order by clause is present on query, but looking carefully on output, officers are retrieved in alphabetical order. <Officer name Beverly Crusher with rank COMMANDER> <Officer name Data with rank LIEUTENANT_COMMANDER> <Officer name Deanna Troi with rank COMMANDER> <Officer name Geordi La Forge with rank LIEUTENANT> <Officer name Jean-Luc Picard with rank CAPTAIN> <Officer name William Riker with rank COMMANDER> <Officer name Worf with rank LIEUTENANT> So who is sorting officer entities? The explanation is on @Sort annotation. In hibernate a sorted collection is sorted in memory being Java the responsible of sorting data using compareTo method. Obviously this method is not the best performance-way to sort a collection of elements. It is likely that we’ll need a hybrid solution between using SQL clause and using annotation instead of writing a query. And this leads us to explain the third possibility, using ordering approach. @OrderBy annotation, available as hibernate annotation and JPA annotation, let us specifies how to order a collection by adding “ order by” clause to generated SQL. Keep in mind that using javax.persistence.OrderBy allows us to specify the order of the collection via object properties, meanwhile org.hibernate.annotations.OrderBy order a collection appending directly the fragment of SQL(not HQL) to order by clause. Now Officer class should not be touched, we don’t need to implement compareTo method nor a java.util.Comparator . We only need to annotate officers field with @OrderBy annotation. Since in this case we are ordering by simple attribute, JPA annotation is used to maintain fully compatibility to other “ JPA ready ” ORM engines. By default ascendent order is assumed. @Entity public class Starship {//code@OneToMany(mappedBy="starship", cascade={CascadeType.ALL}) @OrderBy("name") private List<Officer> officers = new ArrayList<Officer>(); public List<Officer> getOfficers() {return Collections.unmodifiableList(officers);} protected void setOfficers(List<Officer> officers) {this.officers = officers;} public void addOfficer(Officer officer) { officer.setStarship(this); this.officers.add(officer); } }And if we rerun get all officers method, next queries are sent: Hibernate: select starship0_.id as id1_0_, starship0_.affiliationEnum as affiliat2_1_0_, starship0_.launched as launched1_0_, starship0_.height as height1_0_, starship0_.length as length1_0_, starship0_.power as power1_0_, starship0_.width as width1_0_, starship0_.registry as registry1_0_, starship0_.starshipClassEnum as starship9_1_0_ from Starship starship0_ where starship0_.id=?Hibernate: select officers0_.starship_id as starship7_1_1_, officers0_.id as id1_, officers0_.id as id0_0_, officers0_.affiliationEnum as affiliat2_0_0_, officers0_.homePlanet as homePlanet0_0_, officers0_.name as name0_0_, officers0_.rank as rank0_0_, officers0_.speciesEnum as speciesE6_0_0_, officers0_.starship_id as starship7_0_0_ from Officer officers0_ where officers0_.starship_id=? order by officers0_.name ascBoth queries are still executed but note that now select query contains order by clause too. With this solution you are saving process time allowing RDBMS sorting data in a fast-way, rather than ordering data in Java once received. Furthermore OrderBy annotation does not force you to use SortedSet or SortedMap collection. You can use any collection like HashMap, HashSet, or even a Bag, because hibernate will use internally a LinkedHashMap, LinkedHashSet or ArrayList respectively. In this example we have seen the importance of choosing correctly an order strategy. Whenever possible you should try to take advantage of capabilities of RDBMS, so your first option should be using OrderBy annotaion ( hibernate or JPA), instead of Sort. But sometimes OrderBy clause will not be enough. In this case, I recommend you using Sort annotation with custom type (using java.util.Comparator class), instead of relaying on natural order to avoid touching model classes. @Sort(type=SortType.COMPARATOR, comparator=TimeComparator.class)I wish this post helped you to understand differences between “sort” and “order” in hibernate. Keep learning. Reference: Hibernate Tip: Sort and Order from our JCG partner Alex Soto at the One Jar To Rule Them All blog....
android-logo

Java Swing to Android

Here is a quick, brief 10,000ft overview/observations on Android from a Swing developers point of view. Firstly if your coming to Android from Swing you are approaching it with a big advantage to J2EE developers. Now I realise Android doesn’t actually have the AWT/Swing API’s but that doesn’t matter as the general front end/event driven mechanism in it is so close to Swing that you will find it easy. Now Android does rely a lot more on XML defs than Swing ever did and that took me a while to get my head around and realise how powerful a feature it actually it is if used correctly. I started off by buying a couple of books: Learning Android Programming Android I’d recommend both of these as they cover the basics very well, from then on you can use the online Android SDK docs. Other books I’ve seen are not great to be honest, you will be better off googling. Android GUI is like Swing, it’s on a single thread, if you do some heavy lifting on that thread it will cause some issue’s just like with Swing. There are mechanisms and classes available that like SwingWorker help you out (more of this in later blogs). A typical Android screen is created by an Activity class that you have extended. This class typically inflates an XML definition on the screen layout. The XML defines the textfields, comboboxes (called Spinners) and so on. Eclipse is typically used to create the XML (I use the Graphical Layout Tool in Eclipse which is still very buggy but ok). You can also hard code the layouts but I wouldn’t bother as it’s easier to use the XML. The Activities are state driven, they are created, paused, resumed and so on. The states are there because they run on a small device where calls can come in, other programs started an so on. The screens for your app can be hidden, displayed again, killed off and restarted …. You need to handle this and in some cases persist the data. The Activity states are a bit of a head scratcher to start with but once you try a few examples out its straightforward enough. Handling Events from components (Views in Android) is sosimilar to Swing it makes me wonder if somebody copied the event mechanism ;) Any Activity you create needs to be defined in your applications Manifest file, this file is used by the Android device to figure out you apps main class, the icon, theprivilegesit needs and so on. If you don’t specify an Activity on the manifest then the app will stack trace when you attempt to display it. Jumping from screen to screen is done by the use of Intents. Intents are used by Android to signal that you want something to happen. You can create an Intent passing in the class that you want to process the Intent (so say an Activity which displays another screen) or you can ask for some operation, so for instance display this web page, Android in this case would open a browser and display the page. If you had several browsers installed it might ask you which one to use. Android keeps an internal stack so that when the back key is pressed then it will switch back from the browser back to your apps Activity (remember the states I mentioned, your Activity has just had its resume state called ;). Android has some nice features to let you define backgrounds and the look of buttons. This seems to be similar to JavaFX. Basically you can define gradients, patch 9 images (a way of taking a small image and extending it to fit a background nicely), shapes ……. Android comes complete with SQLite3 which is a nice lightweight database. I’ve found it very quick and nice to use. I’ll return to this in another blog as I’m not sure the preferred way to use the database in the most books is actually a good idea. Finally there is a emulator to test your apps on. Its ok, lets you test things on different versions of android and different device specs (screens, memory, input methods (rollers, soft/hard keyboard)) but its slow and really I’d say if you want to really write and app you need atleast one Android device. I have a nice Nexus S Mmmmmm lovely. Anyway thats a very brief overview and when I finish my App I will have some time to spend adding some nice new blogs. Enjoy Reference: Swing to Android from our JCG partner Steve Webb at the Java Desktop Development at the Coal Face blog....
jsf-logo

Integrating Spring & JavaServer Faces : Improved Templating

With the release of version 2.0 Facelet templating became a core part of the JSF specification. Using <ui:composition> and <ui:decorate> tags it becomes pretty easy to build up complicated pages whilst still keeping your mark-up clean. Templates are particularly useful when creating HTML forms but, unfortunately, do tend to cause repetition in your xhtml files, breaking the DRY (Don’t Repeat Yourself) principal of good software design. As part of a project to provide deeper integration between JSF and Spring I have developed a couple of new components that aim to make templating easier. Before diving into the new components, lets look at how a typical form might be built up using standard JSF templates. Often the initial starting point with form templates is to add some boiler plate surround to each input. Often you need extra <div> or <span> tags for your css to use. Here is a typical example: <!-- /WEB-INF/pages/entername.xhtml --> <ui:decoreate template="/WEB-INF/layout/form.xhtml"> <h:inputText id="firstName" label="First Name" value="#{bean.firstName}"/> <ui:param name="label" value="First Name"/> <ui:param name="for" value="firstName"/> </ui:decorate> <ui:decoreate template="/WEB-INF/layout/form.xhtml"> <h:inputText id="lastName" label="Last Name" value="#{bean.lastName}"/> <ui:param name="label" value="Last Name"/> <ui:param name="for" value="lastName"/> </ui:decorate> <!-- Many additional form elements --><!-- /WEB-INF/layout/form.xhtml --> <ui:composition> <div class="formElement"> <span class="formLabel"> <h:outputLabel for="#{for}" label="#{label}"> </span> <ui:insert/> </div> </ui:composition>Here we can see that each item on the form is contained within a <div> and form labels are wrapped in an additional <span>. There is already some repetition in the mark-up, with the “for” parameter mirroring the component ID. I have also given each <h:inputText> element a label attribute for better validation error messages, this is repeated in the “label” <ui:param>. Things start getting worse if we want to mark required fields with an asterisk: <!-- /WEB-INF/pages/entername.xhtml --> <ui:decoreate template="/WEB-INF/layout/form.xhtml"> <h:inputText id="firstName" label="First Name" value="#{bean.firstName}" required="false"/> <ui:param name="label" value="First Name"/> <ui:param name="for" value="firstName"/> <ui:param name="showAsterisk" value="false"/> </ui:decorate> <ui:decoreate template="/WEB-INF/layout/form.xhtml"> <h:inputText id="lastName" label="Last Name" value="#{bean.lastName}" required="true"/> <ui:param name="label" value="Last Name"/> <ui:param name="for" value="lastName"/> <ui:param name="showAsterisk" value="true"/> </ui:decorate> <!-- Many additional form elements --><!-- /WEB-INF/layout/form.xhtml --> <ui:composition> <div class="formElement"> <span class="formLabel"> <h:outputLabel for="#{for}" label="#{label}#{showAsterisk ? ' *' : ''}"> </span> <ui:insert/> </div> </ui:composition>It’s pretty frustrating that we need to pass <ui:param> items that duplicate attributes already specified on the <h:inputText>. It is easy to see how, even for relatively small forms, we are going to end up with a lot of duplication in our mark-up. What we need is a way to get information about the inserted component inside the template, even though we don’t know what type of component it will be. What we need is <s:componentInfo>. The <s:componentInfo> component exposes a variable containing information about the inserted component. This information includes the label, the component clientID and if the component is required. By inspecting the inserted item we can remove a lot of duplication: <!-- /WEB-INF/pages/entername.xhtml --> <ui:decoreate template="/WEB-INF/layout/form.xhtml"> <h:inputText id="firstName" label="First Name" value="#{bean.firstName}" required="false"/> </ui:decorate> <ui:decoreate template="/WEB-INF/layout/form.xhtml"> <h:inputText id="lastName" label="Last Name" value="#{bean.lastName}" required="true"/> </ui:decorate> <!-- Many additional form elements --><!-- /WEB-INF/layout/form.xhtml --> <ui:composition> <s:componentInfo var="info"> <div class="formElement"> <span class="#{info.valid ? 'formLabel' : 'formErrorLabel'}"> <h:outputLabel for="#{info.for}" label="#{info.label}#{info.required ? ' *' : ''}"> </span> <ui:insert/> </div> </s:componentInfo> </ui:composition>Something else that we can now do is tell if the inserted component has failed validation. Notice that the example above will pick the “formErrorLabel” CSS class for components that are not valid. One interesting feature of having the new <s:componentInfo> component is that all the <ui:decorate> tags become identical. We have removed all the repetition inside the tag, but the tag itself is still repeated many times. Here we have one more trick that can help by introducing a new <s:decorateAll> tag. Using <s:decorateAll> allows use to apply a template once for every child component. Here is the updated form mark-up: <!-- /WEB-INF/pages/entername.xhtml --> <s:decoreateAll template="/WEB-INF/layout/form.xhtml"> <h:inputText id="firstName" label="First Name" value="#{bean.firstName}" required="false"/> <h:inputText id="lastName" label="Last Name" value="#{bean.lastName}" required="true"/> <!-- Many additional form elements --> </s:decorateAll><!-- /WEB-INF/layout/form.xhtml --> <ui:composition> <s:componentInfo var="info"> <div class="formElement"> <span class="#{info.valid ? 'formLabel' : 'formErrorLabel'}"> <h:outputLabel for="#{info.for}" label="#{info.label}#{info.required ? ' *' : ''}"> </span> <ui:insert/> </div> </s:componentInfo> </ui:composition>If you want to look at the source code for these components check out the org.springframework.springfaces.template.ui package on springfaces GitHub project. Reference: Integrating Spring & JavaServer Faces : Improved Templating from our JCG partner Phillip Webb at the Phil Webb’s blog....
java-logo

Java Concurrency with ReadWriteLock

Writing multithreaded java applications is not a piece of cake. Extra care must be taken because bad synchronization can bring your application to its knees. The JVM heap is shared by all the threads. If multiple threads need to use the same objects or static class variables concurrently, thread access to shared data must be carefuly managed. Since version 1.5, utility classes commonly useful in concurrent programming is included in the JSDK. In Java synchronized keyword is used to acquire a exclusive lock on an object. When a thread acquires a lock of an object either for reading or writing, other threads must wait until the lock on that object is released. Think of a scenerio that there are many reader threads that reads a shared data frequently and only one writer thread that updates shared data. It’s not necessary to exclusively lock access to shared data while reading because multiple read operations can be done in parallel unless there is a write operation. In this post i’ll give an example usage of ReadWriteLock interface which is introduced in the Java 1.5 API Doc. In Java Api Documentation it says :  A ReadWriteLock maintains a pair of associated locks, one for read-only operations and one for writing. The read lock may be held simultaneously by multiple reader threads, so long as there are no writers. The write lock is exclusive. Reader threads can read shared data simultaneously. A read operation does not block other read operations. This is the case when you execute an SQL SELECT statement. But write operation is exclusive. This means all readers and other writers are blocked when a writer thread holds the lock for modifing shared data. Writer.java This class represents a thread that updates shared data. Writer uses WriteLock of ReadWriteLock to exclusively lock access to dictionary. package deneme.readwritelock; public class Writer extends Thread{ private boolean runForestRun = true; private Dictionary dictionary = null; public Writer(Dictionary d, String threadName) { this.dictionary = d; this.setName(threadName); } @Override public void run() { while (this.runForestRun) { String [] keys = dictionary.getKeys(); for (String key : keys) { String newValue = getNewValueFromDatastore(key); //updating dictionary with WRITE LOCK dictionary.set(key, newValue); } //update every seconds try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } public void stopWriter(){ this.runForestRun = false; this.interrupt(); } public String getNewValueFromDatastore(String key){ //This part is not implemented. Out of scope of this artile return "newValue"; } }Reader.java This class represents a thread that reads share data. package deneme.readwritelock; public class Reader extends Thread{ private Dictionary dictionary = null; public Reader(Dictionary d, String threadName) { this.dictionary = d; this.setName(threadName); } private boolean runForestRun = true; @Override public void run() { while (runForestRun) { String [] keys = dictionary.getKeys(); for (String key : keys) { //reading from dictionary with READ LOCK String value = dictionary.get(key); //make what ever you want with the value. System.out.println(key + " : " + value); } //update every seconds try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } public void stopReader(){ this.runForestRun = false; this.interrupt(); } }Dictionary.java This is a simple and thread safe dictionary. Read operations are managed through ReadLock and write operations (updates) are managed throuh WriteLock. package deneme.readwritelock; import java.util.HashMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class Dictionary { private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); private final Lock read = readWriteLock.readLock(); private final Lock write = readWriteLock.writeLock(); private HashMap<String, String> dictionary = new HashMap<String, String>(); public void set(String key, String value) { write.lock(); try { dictionary.put(key, value); } finally { write.unlock(); } } public String get(String key) { read.lock(); try{ return dictionary.get(key); } finally { read.unlock(); } } public String[] getKeys(){ read.lock(); try{ String keys[] = new String[dictionary.size()]; return dictionary.keySet().toArray(keys); } finally { read.unlock(); } } public static void main(String[] args) { Dictionary dictionary = new Dictionary(); dictionary.set("java", "object oriented"); dictionary.set("linux", "rulez"); Writer writer = new Writer(dictionary, "Mr. Writer"); Reader reader1 = new Reader(dictionary ,"Mrs Reader 1"); Reader reader2 = new Reader(dictionary ,"Mrs Reader 2"); Reader reader3 = new Reader(dictionary ,"Mrs Reader 3"); Reader reader4 = new Reader(dictionary ,"Mrs Reader 4"); Reader reader5 = new Reader(dictionary ,"Mrs Reader 5"); writer.start(); reader1.start(); reader2.start(); reader3.start(); reader4.start(); reader5.start(); } }Reference: ReadWriteLock example in Java from our JCG partner Ilkin Ulas at the All your base are belong to us blog....
json-logo

JSON with GSON and abstract classes

I have switched to Google Gson after many years of using org.json library for supporting JSON data interchange format in Java. org.json is a lower-level library, so that you have to create JSONObject, JSONArray, JSONString, … and do other low-level work. Gson simplifies this work. It provides simple toJson() and fromJson() methods to convert arbitrary Java objects to JSON and vice-versa, supports Java Generics, allows custom representations for objects, generates compact and readability JSON output and has many other goodies. I love it more and more. The using is simple. Assume, we have a class called Circle. public class Circle { private int radius = 10; private String backgroundColor = "#FF0000"; private String borderColor = "#000000"; private double scaleFactor = 0.5; ...// getter / setter }Serialization (Java object –> JSON) can be done as follows: Circle circle = new Circle(); Gson gson = new Gson(); String json = gson.toJson(circle); ==> json is { "radius": 10, "backgroundColor": "#FF0000", "borderColor": "#000000", "scaleFactor": 0.5, ... }Deserialization (JSON –> Java object) is just one line of code: Circle circle2 = gson.fromJson(json, Circle.class); ==> circle2 is the same as the circle aboveEverything works like a charm. There is only one problem I have faced with abstract classes. Assume, we have an abstract class AbstractElement and many other classes extending this one public abstract class AbstractElement { private String uuid;// getter / setter }public class Circle extends AbstractElement { ... }public class Rectangle extends AbstractElement { ... }public class Ellipse extends AbstractElement { ... }Assume now, we store all concrete classes in a list or a map parametrized with AbstractElement public class Whiteboard { private Map<String, AbstractElement> elements = new LinkedHashMap<String, AbstractElement>(); ... }The problem is that the concrete class is undisclosed during deserialization. It’s unknown in the JSON representation of Whiteboard. How the right Java class should be instantiated from the JSON representation and put into the Map<String, AbstractElement> elements? I have nothing found in the documentation what would address this problem. It is obvious that we need to store a meta information in JSON representations about concrete classes. That’s for sure. Gson allows you to register your own custom serializers and deserializers. That’s a power feature of Gson. Sometimes default representation is not what you want. This is often the case e.g. when dealing with third-party library classes. There are enough examples of how to write custom serializers / deserializers. I’m going to create an adapter class implementing both interfaces JsonSerializer, JsonDeserializer and to register it for my abstract class AbstractElement. GsonBuilder gsonBilder = new GsonBuilder(); gsonBilder.registerTypeAdapter(AbstractElement.class, new AbstractElementAdapter()); Gson gson = gsonBilder.create();And here is AbstractElementAdapter: package com.googlecode.whiteboard.json;import com.google.gson.*; import com.googlecode.whiteboard.model.base.AbstractElement; import java.lang.reflect.Type;public class AbstractElementAdapter implements JsonSerializer<AbstractElement>, JsonDeserializer<AbstractElement> { @Override public JsonElement serialize(AbstractElement src, Type typeOfSrc, JsonSerializationContext context) { JsonObject result = new JsonObject(); result.add("type", new JsonPrimitive(src.getClass().getSimpleName())); result.add("properties", context.serialize(src, src.getClass()));return result; }@Override public AbstractElement deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonObject jsonObject = json.getAsJsonObject(); String type = jsonObject.get("type").getAsString(); JsonElement element = jsonObject.get("properties");try { return context.deserialize(element, Class.forName("com.googlecode.whiteboard.model." + type)); } catch (ClassNotFoundException cnfe) { throw new JsonParseException("Unknown element type: " + type, cnfe); } } }I add two JSON properties – one is ” type” and the other is ” properties”. The first property holds a concrete implementation class (simple name) of the AbstractElement and the second one holds the serialized object itself. The JSON looks like { "type": "Circle", "properties": { "radius": 10, "backgroundColor": "#FF0000", "borderColor": "#000000", "scaleFactor": 0.5, ... } }We benefit from the ” type” property during deserialization. The concrete class can be instantiated now by Class.forName(“com.googlecode.whiteboard.model.” + type) where “com.googlecode.whiteboard.model.” + type is a fully qualified class name. The following call public <T> T deserialize(JsonElement json, Type typeOfT) throws JsonParseExceptionfrom JsonDeserializationContext invokes default deserialization on the specified object and completes the job. Reference: JSON with GSON and abstract classes from our JCG partner Oleg Varaksin at the Thoughts on software development blog....
software-development-2-logo

Why Developers Keep Making Bad Technology Choices

Today, software developers are faced with a great abundance of options when choosing how to design and implement systems. We are constantly bombarded with choice and are used to dealing with buzzwords like NoSQL, the cloud, REST, Map-Reduce and so on. However, developers in charge of designing systems can be easily seduced into incorporating technologies that don’t provide a clear benefit over simpler solutions that aren’t as modern or hip. It seems like the KISS principle (Keep it simple, stupid!), while often referenced, is often neglected in favour of more “enterprisey” solutions. Why is this? There are probably a lot of reasons, but I’ve identified a few that I think cover the majority of cases. As professional developers, I feel strongly that we have a duty to our employers to provide the best long-term solutions and therefore we need to rein in our desires when they conflict with this. Software development is not yet in the same realm as medicine or engineering, but I think we do need to make steps towards the professionalism, duty and responsibility that come with working in those fields. Reason #1 – Boredom Developers are often solving the same types of problems over and over. Not all of us have the privilege of working on new types of projects all the time, and even if we are, it’s often not new ground; similar problems have usually been solved thousands of times before by software developers around the globe. It’s no surprise then that we want to try something new, even if we’ve adequately solved a problem before. We are natural puzzle solvers, and sometimes you just want to try a new puzzle. I’m sure many of you with several years of experience have seen functional systems effectively replaced with a new implementation that uses different technologies for no clear reason other than to suit the fancy of new developers. So what do we do about this? How do we scratch that itch for something new? A relational DB is just so boring compared to trying out the latest NoSQL platform. Who cares if we don’t really have a good use for it? Well, I’d say you have a few options. For example, take the initiative and find ways to build out the platform that might actually benefit from some new technology. Other than that, why not work on a pet project in your spare time? After all, our job is to deliver high quality software – not entertain ourselves. Disclaimer: I’m not trying to dissuade anyone from using new technologies. Just identify their benefits and see if they are the best choice for what you are doing, and if what you have doesn’t do the job, go for it! Reason #2 – Resume Padding This is perhaps the saddest of the reasons why developers make poor technology choices, and it mainly affects organizations with poor decision-making processes, but it’s still very common. Contracts and positions in software development are very fluid these days – it’s not uncommon for a developer to be at a new company every year or two. Gone are the days where hopping from job to job is considered a no-no. Since this is the case, a lot of developers leap-frog from position to position to climb the ladder. It’s far easier for an average or lower-skilled developers to get ahead by doing this instead of trying to move up within a single company. Since this is the case, developers will often try to incorporate technologies to get experience in them so as to add a bullet-point to their resume. How useful the technology will be to the platform is of secondary importance. Often it doesn’t matter how much they actually use it – nobody can pretend that people don’t exaggerate their skills when looking for new work. Therefore, platforms from small to large will often end up using untested technologies, or just technologies that nobody in-house actually understands well. Companies are then left with poor systems using too many technologies with nobody to maintain them as developers jump ship to more promising positions. I don’t believe that most developers do this, but those of us who disagree with such actions should work to push back when presented with developers who are trying to make bad choices. Reason #3 – Peer Pressure Peer pressure is perhaps the most difficult cause to resist. We all like to believe that we are independent agents that make our own informed decisions, but all of us are human, and event the most prickly people are social creatures that want to have a happy social group. When faced with new or hip technologies, a lot of us are somewhat afraid to resist implementing something that doesn’t really seem like a good idea to us. But we should suppress this feeling as much as we can. If you are in an environment where discussion and disagreement are valued (as one would hope), you should feel free to voice your concerns even if you aren’t totally familiar with the latest-and-greatest. Remember that software technologies come and go, but the basic principles pretty much stay the same. So if something doesn’t seem to add up, speak up! If you are a junior developer, you should still feel free to add your input – having experience doesn’t make one right. Plus, you could very well gain some insight into the choices that are being made. Reason #4 – Lack of Understanding Finally, technologies are sometimes chosen because developers don’t understand how things are actually working in a platform, or don’t want to find out. For example, if you don’t have experience with highly performant relational databases, you may be inclined to go the NoSQL route, out of fear that you may implement something that won’t scale. Often though, this fear can be unfounded. If you are using a tool improperly, of course it won’t work well. But don’t let lack of understanding or knowledge force you into an unwise course of action. If, in reality, a solution could be implemented well in a relational database, and your platform already uses one, it would be foolish to introduce a new dependency simply because you aren’t familiar with what you have. To avoid this, read and learn! If you are making choices, examine your assumptions and see if they hold up. Consult with senior developers who have worked with the tools in question and ask specifics about what they can and can’t do well. It’s never a waste to learn more about the tools that are available to us, and it will very likely pay dividends well into the future if you take the initiative. Reason #5 – Misunderstanding or Solving Non-Existent Problems This point ties into my previous point a little bit, but it really deserves its own discussion since it is such a big problem. A common theme when developers pitch a new technology is that it does X and Y and protects against Z. But a lot of the time, X, Y and Z were never issues in the first place. For example, if we have a read-only data set that needs to be cached on multiple nodes in a cluster, someone may pitch a caching technology that offers distributed data sets where elements are not duplicated on each node. But what if the data set is small and we don’t anticipate any change that would necessitate distributed caching? We’d be introducing new technology that is inherently slower, more brittle and more complicated for a problem that doesn’t exist! To guard against this, developers need to make sure that they understand the problem domain all the way through, and they also need to cross-check their assumptions to make sure they are correct. Sometimes we assume things that actually aren’t the case, so the latter step is important. Avoid the temptation to cover “what-if” situations. Chances are, you ain’t gonna need it, and if you do, we usually overestimate the cost of making changes at a later date, not realizing we are basically committing to the same effort now to avoid a slim chance of having to do the same amount of work later. So What Should We Do? So what are the rights things to do when choosing technologies? To start with, you might want to review the following points, and try to make it a team decision. The more input you have, the less likely you are to miss a piece of information that might alter your decision.Review the requirements – consistency, failover, performance, etc. Evaluate if what you have can meet the need well. If so, this is almost always the right choice. Investigate how other technologies would meet the need, and factor in the costs of extra dependencies and potential failure points (nothing is free, and every new technology can have significant maintenance costs). Find out your team’s expertise – favour things that you know well. Factor in any other concerns like pricing, timelines, etc. Discuss with the team, and make a pros and cons list.These are just guidelines, and you can approach it any way you like, because the main thing is that you do make the decision carefully and rationally. I hope that nobody takes this article to mean that new technologies are scary or that they should just be avoided! For instance, I’ve used NoSQL as an example already. I believe it definitely fills a need that exists and I’ve used it before to solve specific problems, but sometimes I think we get caught up in the fun stuff, and forget our ultimate goals. Just keep your objectives in mind and try to make the best long-term choice. Reference: Why Developers Keep Making Bad Technology Choices from our JCG partner Craig Flichel at the Carfey Software Blog blog....
apache-camel-logo

SOA example application

SOA describes a set of patterns for creating loosely coupled, standards-based business-aligned services that, because of the separation of concerns between description, implementation, and binding, provide a new level of flexibility. Service Oriented Architecture terminology has spread in recent years, at least among people who were involved in most of the Information Technology activities. The guidelines suggested by this methodology are granted as major factors to succeed in different distributable systems domains. Just as the definition is clear and easy to understand, so is its implementation into a real project, being intuitive, concise and elegant. I have released an application demonstrating how SOA?s principles can be applied into a small project making use of EIP (Enterprise Integration Pattern), IoC (Inversion of Control), and a building tool and scripting language such as Groovy. I analized a simple business case: an entertainment provider who wanted to dispatch rewards and bonuses to some of its customers, depending on customer service?s subscriptions. The process sequence is simple:  It is required to provide an implementation of a RewardsService. The service accepts as input a customer account number and a portfolio containing channels subscriptions.The Customer Status team is currently developing the EligibilityService which accepts the account number as an input. I set up an infrastructure to write acceptance tests for this first meaningful feature. This is what could be defined as a ?walking skeleton,? a prototype with the essential aspect that it could be built, deployed and tested after being easily downloaded from Github.RewardService is invoked by the client and it calls, in turn, the eligibility service whichhowever, in this case is not implemented. As many real scenarios expect external services, this proof-of-concept refers the eligibility service to a black-box, where only request/response interface is known. The unit testsimulates the eligibility servicebehaviorsmocking the end-point through the Camel Testing Framework. However, if you want to run the application on your local machineI set up, within a line of code, a faux eligibility service that merelyreturns a positive response: def alwaysEligible = {exchange -> if(exchange){exchange.getOut().setBody('CUSTOMER_ELIGIBLE')}} as Processor The entry point is an HTTP Restful interface built upon the Apache CXF, and is easily set up within few lines in theconfiguration. CXF is initialized by Spring in this following way: jaxrs.'server'(id:'restService',address:'http://${http.host}:${http.port}') {jaxrs.'serviceBeans'{ ref(bean:'rewardService')} } Services are connected by Apache Camel. RewardService contains only the reference of the ESB context – an instance of ProducerTemplate. Such solution allows a complete separation between the linking system and the business services.The Camel context represents the SOA’s wiring, and is configured through a DSL as in the example below: from('direct:rewards').to(eligibilityServiceEndpoint) Reference: SOA example application from our JCG partner Giancarlo Frison at the Making Things Simple Through The Complex blog....
codehaus-jetty-logo

Setting up JNDI with Jetty (Embedded)

I was running embedded Jetty on my developmentwork-space saving some time on vicious cycle of compiling and deployment. I have not worked with Jetty much and the ease of use made me hook on to it. I was in need to setup JNDI in order to retrieve a connection pool for my database related activities. Though there were comprehensive documentation in some places, most were scattered. So this post is intended to be your one stop place for the requirement of setting up JNDI with Jetty. If it does not, please do leave a comment and i will be glad to help you out. So starting off, first let us see how to setup Jetty to run as an embedded server. The folder structure of my eclipse project is as follows;The etc folder will consist of all the configuration files required by jetty. You can download jetty from here. For this example i have usedjetty-6.1.26. Include the following jars from the given folder locations;lib jetty-x.x.xx.jar, jetty-util-x.x.xx.jar,servlet-api-x.x.jarlib/plus jetty-plus-x.x.xx.jarlib/naming jetty-naming-x.x.xx.jarFor my example, i have set up mysql and therefore mysql-connector jar is also included in my library path. Copy all the files residing in your jetty installation’s etc directory to the etc directory of your eclipse project. In order to enable JNDI, we first need to include jetty-plus. There are many ways you can do this such as providing it as arun-timeargument, including it within your own jetty-env.xml residing in your WEB-INF or copying and pasting the required xml snippets from the jetty-plus.xml to your jetty.xml. I have chosen the latter. Hence, i have included the following snippet within my jetty.xml; <Array id="plusConfig" type="java.lang.String"> <Item>org.mortbay.jetty.webapp.WebInfConfiguration</Item> <Item>org.mortbay.jetty.plus.webapp.EnvConfiguration</Item> <Item>org.mortbay.jetty.plus.webapp.Configuration</Item> <Item>org.mortbay.jetty.webapp.JettyWebXmlConfiguration</Item> <Item>org.mortbay.jetty.webapp.TagLibConfiguration</Item> </Array><call name="addLifeCycle"> <arg> <new class="org.mortbay.jetty.deployer.WebAppDeployer"> <set name="contexts"><ref id="Contexts"></ref></set> <set name="webAppDir"><systemproperty default="." name="jetty.home">/webapps</systemproperty></set> <set name="parentLoaderPriority">false</set> <set name="extract">true</set> <set name="allowDuplicates">false</set> <set name="defaultsDescriptor"><systemproperty default="." name="jetty.home">/etc/webdefault.xml</systemproperty></set> <set name="configurationClasses"><ref id="plusConfig"></ref></set> </new> </arg> </call>Next up, you need to add the XML fragment related to your data-source into your jetty.xml. I have added the snippet required for mysql. For any other database, please check this link. <New id="myds" class="org.mortbay.jetty.plus.naming.Resource"><Arg>jdbc/MySQLDS</Arg> <Arg> <New class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource"> <Set name="Url">jdbc:mysql://localhost:3306/test</Set> <Set name="User">root</Set> <Set name="Password">password</Set> </New> </Arg> </New>Now that we have setup everything, all you need to do is run jetty in your embedded environment. Following code shows you how to run Jetty in the embedded mode as part of your main class; import java.io.File;import org.mortbay.jetty.Handler; import org.mortbay.jetty.Server; import org.mortbay.jetty.handler.DefaultHandler; import org.mortbay.jetty.handler.HandlerList; import org.mortbay.jetty.webapp.WebAppContext; import org.mortbay.xml.XmlConfiguration;public class JettyTest {public static void main(String[] args) throws Exception { Server jetty = new Server(); String[] configFiles = {"etc/jetty.xml"}; for(String configFile : configFiles) { XmlConfiguration configuration = new XmlConfiguration(new File(configFile).toURI().toURL()); configuration.configure(jetty); } WebAppContext appContext = new WebAppContext(); appContext.setContextPath("/myapp"); File rd = new File("path_to_your_war_file"); appContext.setWar(rd.getAbsolutePath()); HandlerList handlers = new HandlerList(); handlers.setHandlers(new Handler[]{ appContext, new DefaultHandler()}); jetty.setHandler(handlers); jetty.start(); } }Thats about it. Now you can look up your data-source which is exposed from Jetty. For ease, i have configured it with Spring’s JNDIObjectFactoryBean. One important aspect to note is the jndi provider URL and the initial context factory entries required for Jetty. <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate"> <property name="environment"> <props> <prop key="java.naming.factory.initial">org.mortbay.naming.InitialContextFactory</prop> <prop key="java.naming.provider.url">org.mortbay.naming</prop> </props> </property> </bean> <bean id="jndiDataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiTemplate"> <ref bean="jndiTemplate"/> </property> <property name="jndiName"> <value>jdbc/MySQLDS</value> </property> </bean>With that you have all that you need to configure JNDI and access it through Spring’s JNDI template. One other thing i was interested in was remote debugging with jetty server. After some searching i found that you need to include the following in your runtime configuration as VM arguments; -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000 This will enable you to remote debug your application on port 8000. If there are any queries please do leave a comment and i will be more than happy to help anyone. And ofcourse if you do see any error, leave a reply too which again is much appreciated :). Reference: Setting up JNDI with Jetty (Embedded) from our JCG partner Dinuka Arseculeratne at the My Journey Through IT blog....
javafx-logo

FXML: Custom components using BuilderFactory

When you want to use FXML, you will need to be able to add your own components. That’s fairly easy, you simply need to add an import statement. Elements in your FXML-file that start with a capital letter will be interpreted as instances, and if they’re Java Beans, most important: if they have a parameterless standard constructor, everything is fine. If not, it’s a bit more complicated. You will need to provide a Builder and a BuilderFactory to the loader. As an example, in FXExperience Tools a nice ColorPicker control is used, that needs a Color passed to it’s constructor. So in FXML we want to write something like this: <?import com.fxexperience.javafx.scene.control.colorpicker.ColorPicker?><!-- ... --><ColorPicker fx:id="colorPicker" id="colorPicker" color="GREEN" /> Now we need to create a BuilderFactory and a Builder: import com.fxexperience.javafx.scene.control.colorpicker.ColorPicker; import javafx.fxml.JavaFXBuilderFactory; import javafx.scene.paint.Color; import javafx.util.Builder; import javafx.util.BuilderFactory;/** * * @author eppleton */ public class ColorPickerBuilderFactory implements BuilderFactory {public static class ColorPickerBuilder implements Builder<ColorPicker> { private Color color = Color.WHITE; private String id="colorPicker";public String getId() { return id; }public void setId(String id) { this.id = id; }public Color getColor() { return color; }public void setColor(Color color) { this.color = color; }@Override public ColorPicker build() { ColorPicker picker = new ColorPicker(color); picker.setId(id); return picker; } } private JavaFXBuilderFactory defaultBuilderFactory = new JavaFXBuilderFactory();@Override public Builder<?> getBuilder(Class<?> type) { return (type == ColorPicker.class) ? new ColorPickerBuilder() : defaultBuilderFactory.getBuilder(type); } }And finally when loading the FXML you need to pass the factory to your loader: (Parent) FXMLLoader.load( TestTool.class.getResource("GradientEditorControl.fxml"), null, new ColorPickerBuilderFactory())That’s it, would be cool if I could make SceneBuilder understand that as well. Reference: Add custom components to FXML using BuilderFactoryfrom our JCG partner Toni Epple at the Eppleton blog....
software-development-2-logo

The Greatest Developer Fallacy Or The Wisest Words You’ll Ever Hear?

“I will learn it when I need it“! I’ve heard that phrase a lot over the years; it seems like a highly pragmatic attitude to foster when you’re in an industry as fast-paced as software development. On some level it actually IS quite pragmatic, but on another level I am annoyed by the phrase. It has become a mantra for our whole industry which hasn’t changed said industry for the better. The problem is this, in the guise of sounding like a wise and practical developer, people use it as an excuse to coast. There is too much stuff to know, it is necessary to be able to pick certain things up as you go along – part of the job. But, there is a difference between having to “pick up” some knowledge as you go along and doing absolutely everything just-in-time. The whole industry has become a bunch of generalists, maybe it has always been this way, I just wasn’t around to see it, either way I don’t like it. Noone wants to invest the time to learn anything really deeply, not computer science fundamentals, not the latest tech you’re working with, not even the language you’ve been coding in every day, for the last few years. Why bother, it will be replaced, superseded, marginalised and out of fashion before you’re half way done. I’ve discussed this with various people many times, but noone seems to really see it as a problem. “Just being pragmatic dude“. In the meantime we’ve all become clones of each other. You want a Java developer, I am a Java developer, you’re a Java developer, my neighbour is a Java developer. What differentiates us from each other – not much! Well, I’ve got some jQuery experience. That’s great, so you know how to build accordion menu then? Sure, I Google it and steal the best code I find :). In the meantime, if you need to hire a REAL expert (in anything, maybe you’re writing a fancy parser or need to visualise some big data), I hope you’ve stocked up on beer and sandwiches cause you’re gonna be here a while. Ok, there are ways to differentiate yourself, I have better communication skills, which is why I do better. That’s important too, but, developers differentiating themselves based on soft skills rather than developer skills – seems a bit twisted. We all communicate really well but the code is a mess :). Hell, I shouldn’t really talk, I am a bit of a generalist too. Of course I’d like to think of myself as a T-shaped individual, but if we’re completely honest, it’s more of a dash-shaped or underscore-shaped with maybe a few bumps :). To the uninitiated those bumps might look like big giant stalactites – T-shaped indeed. You seem like an expert without ever being an expert, just one advantage of being in a sea of generalists. Investing In Your Future I don’t want to preach about how we should all be investing in our professional future, everybody knows we should be. Most people probably think they are infact investing, they rock up to work, write a lot of code maybe even do some reading on the side, surely that must make them an expert in about 10 years, and a senior expert in 20 (I keep meaning to write more about this, one day I’ll get around to it :))? But, if that was the way, every old person would be an expert in a whole bunch of stuff and that is emphatically not the case. Maybe it is just that people don’t know how to build expertise (there is an element of truth to this), but I have a sneaking suspicion that it’s more about lack of desire rather than lack of knowledge. What was that saying about the will and the way – totally applicable in this case? I’ve gone completely off-track. “Investing in professional future” is just one of those buzzword things, the mantra is “I will learn it when I need it“. It was good enough for my daddy and it has served me well so far. Let’s apply this thinking to finance, “I will invest my money when I think I need the money“. Somehow it doesn’t quite have the same kind of pragmatic ring to it. You Don’t Know What You Don’t Know We’ve all had those moments where you’re going through major pain trying to solve a problem until someone comes along and tells you about algorithm X or technology Y and it makes everything fast and simple. It was lucky that person just happened to be there to show you the “easy” way, otherwise you would have spent days/weeks trying to figure it out and it would have been a mess. You can’t be blamed for this though, you don’t know what you don’t know. For me, this is where the “I will learn it when I need it” mentality falls over. You can’t learn something if you don’t know it exists. Google goes a long way towards mitigating this problem, but not all the way. There are plenty of problems you will encounter in the wild where you can beat your head against the wall ad infinitum unless you know what class of problem you’re looking at (e.g. if you know a bit about searching and constraint propagation, solving sudoku is easy, otherwise it’s really quite hard). You can’t learn about an algorithm if you’re not aware of it or its applicability. You can’t utilise a technology to solve a problem if you don’t even realise it has that capability. You’re not going to always have someone there to point you in the right direction. I am willing to bet there is a billion lines of code out there right now which can be replaced with a million lines of faster, cleaner, better code simply because whoever wrote it didn’t know what they didn’t know. I seem to be making a case for the opposite side here, if knowing what you don’t know is the ticket then surely we should be focusing on breadth of knowledge. Superficial awareness of as much stuff as possible should see us through, we’ll be able to recognise the problems when we see them and then learn what we need more deeply. Except it doesn’t work like that, skimming subjects doesn’t allow you to retain anything, our brain doesn’t work that way. If we don’t reinforce and dig deeper into the concepts we quickly page that information out as unimportant, it is a waste of time (think back to cramming for exams, how much do you remember the next day?). However if you focus on building deeper understanding of a subject – in an interesting twist – you will gain broad knowledge as well (which you will actually be able to retain). My grandad is a nuclear physicist, several decades of working to gain deeper knowledge of the subject has made him an expert, but it has also made him an excellent mathematician, a decent chemist, a pretty good geologist, a fair biologist etc. Just some empirical evidence that seeking depth leads to breadth as a side-effect. Can You Learn It Fast Enough Some stuff just takes a long time to learn. I am confident I can pick up an ORM framework I haven’t seen before without even breaking stride, I’ve used them before, the concepts are the same. But what if you need to do some speech to text conversion, not quite as simple, not enough background. Hopefully Google will have something for us to copy/paste. That was a bad example, only research boffins at universities need to do that crap. How about building a website then, we all know how to do that, but what if you need to do it for 10 million users a day. We just need to learn everything about scaling, I am sure the users will wait a month or two for us to get up to speed :). Yeah, I am just being stupid, all we need to do is hire an expert and … errr … oh wait, we’re all out of beer and sandwiches. Why Should I Care Working with experts is freaking awesome. You may have experienced it before, everything they say is something new and interesting, you learn new tricks with every line of code, you can almost feel your brain expanding :). You want to learn from the experts, so it’s really sad when you can’t find any. Since everyone is only learning when they “need it“, noone can teach anything to anyone. The chunk of wisdom here is this, you want to work with experts, but the experts also want to work with experts, so what are you doing to make sure the experts want to work with you? Being able to learn something when you need it is a good skill to have, but you can not let it be your philosophy as a developer. Yes it is a big industry you can’t learn everything, so pick something and make sure you know it backwards, if you’re curious enough to follow up on the interesting bits, you’ll find you have a decent grasp of a lot of other stuff at the end. And if you do a good enough job, other super-awesome-smart people are going to want to come and hang around you cause they’ll be able to learn something from you and you’ll be able to learn much from them. Everybody will be a winner. Reference: The Greatest Developer Fallacy Or The Wisest Words You’ll Ever Hear? from our JCG partner Alan Skorkin at the Skorks blog....
Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close