How to develop/deploy CQ5 code using an OSGi bundle
February 16, 2012
For those that develop CQ5 components, most people will be familiar with CRXDE or Eclipse to develop CQ5 components and OSGi bundles. The usual unit of deployment is a CRX package either created using the Package Manager or some build script offline using the vault format. The CQ5 package will contain inside it one or more OSGi bundles which are then picked up by the JCR Installer and deploy it to Apache Felix.
There is one other way of deploying code to CQ5 and that is using OSGi bundles with the JCR content bundled as resources inside the bundle itself. This mechanism is used by the applications developed on Apache Sling. Since CQ5 components are essentially Sling applications, I thought I’d describe how to go about doing offline development and deployment of an example CQ5 component using maven.
Let’s start with the pre-requisites:
- A local CQ5 instance
- Maven
- A maven repository with the OSGi bundles OR Install the Archiva Servlet (link) on CQ5
Let’s assume you have these ready.
The first thing you need is a project structure and a pom file.
In my app, I created a project structure as follows:
sample-sling-app/
pom.xml
src/main/java/
com/technomaven/samples/
SomeService.java
com/technomaven/samples/impl
SomeServiceImpl.java
src/main/resources/SLING-CONTENT/
apps/technomaven/components/
testcomponent/
testcomponent.jsp
testcomponent.json
apps/technomaven/templates/
apps/technomaven/config/
etc/designs/my-sling-app/
my-sling-app.json
This source structure will produce the jar file which includes the java classes (contained in src/main/java) and the JCR nodes, properties, and files that constitute the CQ5 components (contained in src/main/resources/SLING-CONTENT). You’ll notice the CQ5 folders for apps and etc/designs/ are there. You can add any other folders there too.
First a look at the pom.xml
Most of this is your usual maven configuration of the dependent libraries. If we concentrate on the plugins section, there are three plugins:
- maven-scr-plugin
- maven-bundle-plugin
- maven-sling-plugin
maven-scr-plugin is used to use the scr annotations in the java classes to register or wire the OSGi services.
maven-bundle-plugin uses BND to produce the OSGi bundle with the correct MANIFEST.MF contents. Note the entries in the configuration element. These include the Export-Package, Import-Package, Private-Package headers found in your typical OSGi bundle. The extra element here is the Sling-Initial-Content element which includes declarations of what parts of the bundle should be used to initialise content in the JCR (CRX in our case).
If we look closely, we have several entries delimited by commas:
Each entry contains the location in the bundle, a flag to overwrite in the repository, a flag to install the content on uninstall of the bundle, and the path in the repository that the contents should be written.
The actual contents of SLING-CONTENT can be specified according to the Sling Content Loader mechanism (more detail here)
Each folder represents a folder in CRX. Each node and its children and properties can be defined in a json file.
In the Sling-Initial-Content above, you will notice two entries for /etc/designs/my-sling-app. One for the the /etc/designs/my-sling-app node itself (which is of type cq:Page) and another for the its child (jcr:content) and child nodes and properties of jcr:content.
The third plugin (maven-sling-plugin) is used to install the bundle to Apache Felix in the install phase of mvn execution.
That’s it. Run mvn clean install from commandline and this will be installed on your local CQ5 instance and overwrite your OSGi bundle, /apps/technomaven, and /etc/designs/my-sling-app folders in CRX.
The full package of the code above can be found here. Enjoy.
Introduction
I’ve been working on projects using Apache Sling and Day (Adobe) CQ5 where the back-end Java code is packaged and deployed as OSGi bundles.
The IDE provided for CQ5 development is CRXDE and it provides a very easy mechanism for developing and building OSGi bundles. (More on CRXDE here) The wizard creates a bundle with a default BND descriptor file which can be edited to specify the package exports and imports according to the functionality of the bundle. It also creates a default Activator class but I haven’t had to use it too much as we use SCR Annotations with our Java classes to register resources such as Sling Servlets or Services. (More on SCR Annotations here) The Java code resides in the JCR repository (CRX in the case of CQ) and CRXDE builds this on the server and deploys the bundle to Apache Felix via JCR Install (a mechanism built on the File Install service). This process is very transparent and is convenient for developers who want to get up and running very quickly without the headaches of setting up local build environments, checking out code from source control, writing and tweaking build scripts until finally something is deployed and working on the server.
However, for settings where multiple developers are working on the same code and the build and deploy scripts are approximating/mirroring those for continuous integration and deployment to test and production environments, it is useful to familiarise oneself with building and deploying offline. It gives the developer functionality to make use of their IDE of choice to take advantage of various plugins for code completion, checkstyles, etc. I prefer Eclipse among the IDEs I’ve worked with.
One of the ways to build the OSGi bundles is using Maven and make use of plugins such as the maven-bundle-plugin and maven-scr-plugin. Most projects I’ve worked on had maven projects and we used maven to manage our builds. An example of the maven setup to build and deploy OSGi bundles can be found in the Apache Sling project source code.
I came across Gradle (an alternative build tool based on Groovy) a while ago and I thought I’d try and teach myself by building something that I know how to do it in maven–building an OSGi bundle with SCR support.
Prerequisites
- Gradle (1.0+)
- Maven repository with dependencies required for the bundle
Sample build.gradle file:
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'osgi'
repositories {
mavenCentral()
mavenRepo urls: ['http://localhost:4502/maven/repository']
}
configurations {
provided
compile.transitive = true
}
dependencies {
provided (
[group: 'org.osgi', name: 'org.osgi.core', version: '4.1.0'],
[group: 'org.osgi', name: 'org.osgi.compendium', version: '4.1.0'],
[group: 'org.apache.sling', name: 'org.apache.sling.rewriter', version: '1.0.0'],
[group: 'org.apache.sling', name: 'org.apache.sling.jcr.api', version: '2.1.0'],
[group: 'com.day.cq', name: 'cq-commons', version: '5.4.6'],
[group: 'com.day.cq', name: 'cq-security', version: '5.4.8'],
[group: 'com.day.cq', name: 'cq-security-api', version: '5.4.4'],
[group: 'com.day.cq.wcm', name: 'cq-wcm-foundation', version: '5.4.2'],
[group: 'org.slf4j', name: 'slf4j-api', version: '1.4.3'],
[group: 'org.slf4j', name: 'slf4j-simple', version: '1.5.2'],
[group: 'org.apache.sling', name: 'org.apache.sling.api', version: '2.2.0'],
[group: 'javax.servlet', name: 'servlet-api', version: '2.4'],
[group: 'org.apache.felix', name: 'org.apache.felix.scr.ant', version: '1.1.0' ],
[group: 'javax.jcr', name: 'jcr', version: '2.0' ],
[group: 'org.apache.felix', name: 'org.apache.felix.webconsole', version: '3.1.8' ],
[group: 'org.apache.felix', name: 'org.apache.felix.scr.annotations', version: '1.5.0' ]
)
}
sourceCompatibility = 1.6
group = 'com.day.myapp'
version = '0.1-SNAPSHOT'
ant.properties.src = 'src/main/java'
ant.properties.classes = 'build/classes/main'
task genscr(dependsOn: compileJava) << {
println ant.properties.classes
ant.taskdef(resource: 'scrtask.properties', classpath: configurations.provided.asPath )
ant.scr(srcdir: ant.properties.src, destdir: ant.properties.classes, classpath: configurations.provided.asPath)
}
jar.dependsOn(genscr)
jar {
manifest {
version = '0.1.0.SNAPSHOT'
symbolicName = 'com.day.myapp.core'
instruction 'Import-Package', '*'
instruction 'Export-Package', 'com.day.myapp.*'
instruction 'Bundle-Activator', 'com.day.myapp.Activator'
instruction 'Service-Component', 'OSGI-INF/serviceComponents.xml'
instruction 'Test', 'test'
}
}
uploadArchives {
repositories {
flatDir(dirs: file('repos'))
}
}
sourceSets.main.compileClasspath += configurations.provided
Let’s go through the build file.
apply plugin: 'java' apply plugin: 'maven' apply plugin: 'osgi'
These three lines tell gradle that we are building a Java project and will need some maven and OSGi related functions when building the project.
repositories {
mavenCentral()
mavenRepo urls: ['http://localhost:4502/maven/repository']
}
These add maven repositories to look for dependencies during compile and build time. The second maven repository is a custom one in our CQ5 instance through the ArchivaServlet which exposes all OSGi bundles installed in CQ5 as a maven repository.
configurations {
provided
compile.transitive = true
}
This I think is a named list of dependency scopes like maven (test, compile, provided, etc).
dependencies {
provided (
[group: 'org.osgi', name: 'org.osgi.core', version: '4.1.0'],
[group: 'org.osgi', name: 'org.osgi.compendium', version: '4.1.0'],
[group: 'org.apache.sling', name: 'org.apache.sling.rewriter', version: '1.0.0'],
[group: 'org.apache.sling', name: 'org.apache.sling.jcr.api', version: '2.1.0'],
[group: 'com.day.cq', name: 'cq-commons', version: '5.4.6'],
[group: 'com.day.cq', name: 'cq-security', version: '5.4.8'],
[group: 'com.day.cq', name: 'cq-security-api', version: '5.4.4'],
[group: 'com.day.cq.wcm', name: 'cq-wcm-foundation', version: '5.4.2'],
[group: 'org.slf4j', name: 'slf4j-api', version: '1.4.3'],
[group: 'org.slf4j', name: 'slf4j-simple', version: '1.5.2'],
[group: 'org.apache.sling', name: 'org.apache.sling.api', version: '2.2.0'],
[group: 'javax.servlet', name: 'servlet-api', version: '2.4'],
[group: 'javax.jcr', name: 'jcr', version: '2.0' ],
[group: 'org.apache.felix', name: 'org.apache.felix.scr.ant', version: '1.1.0' ],
[group: 'org.apache.felix', name: 'org.apache.felix.webconsole', version: '3.1.8' ],
[group: 'org.apache.felix', name: 'org.apache.felix.scr.annotations', version: '1.5.0' ]
)
}
This is a list of dependencies I needed to compile and build the osgi bundle. The last 3 dependencies were used to generate the SCR descriptor for the OSGi classes with SCR Annotations in them.
task genscr(dependsOn: compileJava) << {
println ant.properties.classes
ant.taskdef(resource: 'scrtask.properties', classpath: configurations.provided.asPath )
ant.scr(srcdir: ant.properties.src, destdir: ant.properties.classes, classpath: configurations.provided.asPath)
}
This is a groovy version of an ant target which calls the ant SCR task as there isn’t yet support for SCR in Gradle’s osgi plugin. The ant task looks in the build/classes folder for the generated classes and then generates a serviceComponents.xml file which describes all the OSGi components and services to be registered in the bundle.
jar.dependsOn(genscr)
This tells gradle that the jar task is dependent on the genscr task where the SCR descriptor is created.
jar {
manifest {
version = '0.1.0.SNAPSHOT'
symbolicName = 'com.day.myapp.core'
instruction 'Import-Package', '*'
instruction 'Export-Package', 'com.day.myapp.*'
instruction 'Bundle-Activator', 'com.day.myapp.Activator'
instruction 'Service-Component', 'OSGI-INF/serviceComponents.xml'
instruction 'Test', 'test'
}
}
This tells the jar task to create the MANIFEST.MF file for the OSGi bundle. The osgi plugin internally uses Peter Krient’s BND tool to generate the final MANIFEST.MF file. THe patterns used here in each of the “instruction” lines are the same that we’d use in a .bnd file.
uploadArchives {
repositories {
flatDir(dirs: file('repos'))
}
}
This task just deploys the file to a given repository, which in this case is a folder on the local file system. I haven’t actually used any mechanism to deploy the bundle to the OSGi container but that part is open to whatever mechanism the project uses. We use maven-sling-plugin to use HTTP POST to deploy the bundle to CRX which in turn uses JCR Install to install and start the bundle. This could just as well use File Install.
To build, have the source code under src/main/java like the typical maven project, and keep the build.gradle file in the root folder. Then run
> gradle jar
or
>grade uploadArchives
Things I wish my university programming courses taught…
September 21, 2010
Having attended interviews for programming jobs and sitting in on other people’s interviews, I had this thought–Maybe we’re expecting too much of fresh graduates given what is taught in university? Now, I understand what a difficult and expensive process it is for companies to find and hire good candidates. We expect fresh graduates to know how programming in industry works without asking where they are supposed to have picked up those skills. We assume that they have either been taught that sort of thing at university or that they have picked it up by themselves by being passionately involved in programming on their own or freelancing for companies. The problem is, how many universities teach the things that companies want? And how many university graduates are involved in programming aside from university coursework or projects? It would be interesting to see some surveys and studies around the gaps between what employers want and what university curriculums teach.
From my experience (having gone through a 4-year undergraduate degree in Computer Engineering), I have to say that much of the “Learning how to learn” approach of teaching was good but not quite there in terms of preparing us to for jobs that required some rather concrete knowledge of programming for industry. Some of the concepts I wish our courses or projects had are:
1. Automated build processes and tools (like ant, maven, etc)
2. Source control (checkins, commits, updates, merges…)
3. Web programming (web servers, application servers, latest frameworks)
4. Introduction to the latest concepts in industry such as dependency injection, SOA, ESBs, etc etc.
5. Bug trackers
6. Templating (html, css, javascript, JSP/PHP/etc)
7. Scripting languages (shell, groovy, etc)
8. Examples of industry software (Databases, business apps, web apps, data warehousing, etc etc)
Of course you can probably have whole courses on each of these and the objective of universities is not to do that but introductions to these concepts via examples or project courses would have been very beneficial. It might be that many professors have not worked in industry since the early days or have worked on projects which didn’t involve any of these. In such a situation, I’m not sure who is best placed to initiate enhancements of the curriculum but I would imagine those involved in the Professional Associations and Accreditation Boards need to do those. If this happens, more and more candidates will face interviews having to defend why they did not learn all this stuff themselves. Even if somebody was passionate about programming and learned all of this, this does not represent the majority of students and as such we are leaving behind a big group of people who would have otherwise been the next generation of engineers and progammers. I feel for the money spent on getting a university degree these days, they could do a lot better. And if they are not equipped, then there is probably a market place for companies in industries to enter that WOULD create the people with the skills they need. Imagine a software company that takes in a class of programmers each year, charging a fraction of the tuition paid to universities, and teach 4-5 courses covering the basic knowledge required to work in industry. I would say a year’s worth of training (free or chargeable) is a win-win situation for both fresh graduates and companies. Now that would make universities wake up and not be so complacent about the business they are in. And it would make the process of hiring experienced people a lot more easier knowing that they’ve received industry specific training which could set the standards required for educational and vocational institutions claiming they are readying students for industry.
How do you do basic ajax?
June 13, 2008
This is a post for all web developers who’re on my friends list or passing by my journal.
So I’ve been playing with Ajax related technologies for a little over a year now and there seems to be so many ways of doing things that it’s become this mish mash of things good and crap. The way I like to use Ajax is making use of XmlHttpRequest or the ajax framework of choice to make the calls to the server end, get the appropriate data (or process it if need be on the server end) and then doing some UI rendering on the client end after that. Now, the natural way to do this of course is in a javascript callback function where you’d start modifying elements in your page. Question is, how do you do that? I’ve come across three (well, I had one sort of literally shoved down my throat that left a bad after taste) and I’ll write them out.
1. Get back the response object, and then insert the data appropriately by making the xml dom object methods.
2. Get back the response object, and then create a whole bunch of html in a string and pass that into the innerHTML of some div element. This is still acceptable for me where I might have to consider the implications of browser-specific issues with dom method usage. The classic one I’ve found is when I have to write setAttribute(“class”, something) AND setAttribute(“className”, something) for it to work on IE and Firefox. If I just wrote a string and passed it to innerHTML, I can just write the html in it that would be more browser friendly than the dom methods.
3. Get back the response object which itself has presentation logic that the client just pass to innerHTML of a UI element. Am I being snobbish or elitist to think that this is stupidness? Or maybe it’s the object oriented programmer in me squirming to still maintain elements of object oriented programming in a programming domain where you have to use a whole bunch of hacks to do anything that resembles good coding practices (which then nullifies the effort to bring about some order to the way we integrate html with back end systems). It’s not that I’m just being a purist in not wanting to receive presentation content directly from a server call that was meant to be a search or an action. It’s just that this approach seems to make programming more like taking a whole bunch of darts and flinging them at a dartboard and hoping that somehow they all stick in the right order in the right place. Debugging any problems becomes a nightmare. Not only that, whoever’s going to come maintain this code after you leave is going to curse you for being an insensitive git.
So here’s my question to all you web developers out there. What’s your take on all of this? I think web developments is one arena where programmers with various different backgrounds mingle and can share ideas. I’d like to hear your arguments to sway me to the third option above. (or hear validating arguments to let me know that I’m not insane).
AJAX Portlet using DWR, Javascript Templates (JST)
March 31, 2008
After having developed several JSR 168 Portlets that were AJAX enabled, I thought it would be beneficial to look for a combination of tools and frameworks that would minimize the numerous problems that crop up in developing dynamic portlets. The benefit of using AJAX in portlets is obvious in that it allows for the ability to develop highly interactive portlets that do not require the entire page to be refresed for each update. Portal pages can get quite heavy with portlets and each page load (even with some form of caching in the backend) is wasteful when all that needs to be updated is the individual portlet.
The two main problems that I have faced in portlet development with AJAX were:
1. Finding a simple and powerful framework for AJAX to integrate javascript with backend java code.
2. Finding the best way to keep UI code cleanly separated from logic in javascript/java.
The first problem was really a matter of finding a solution to the mismatch Java code and then code required to integrate the client side using XMLHttp or XMLHttpRequest. Luckily, DWR has been in existence for a while and provides a neat solution for exposing backend Java methods as Javascript functions. A DWRServlet has to be bundled with the application that acts as the gateway between javascript and the POJOs on the server by way of configurations in a dwr.xml file or in the spring application context file. The DWRServlet produces the right javascript proxies so that client-side javascript can invoke methods using the same class and method names.
For example, if I have a method in the backend called AjaxHelper.callMethod() in java, an AjaxHelper.callMethod() function can be invoked in javascript with the latest parameter in the function being a javascript callback function to update the UI. Out of the box, different java objects are automatically converted to javascript objects. These include Date, JavaBeans, Lists, etc. Should any custom objects need to be converted, mechanisms exist to define those. As well, Java Exceptions can be converted and handled appropriately on the client side. One thing to note here is that the since the DWRServlet is bundled with the portlet, the portal framework has to allow for resources within the portlet war to be accessed under the /dwr subcontext. There may be a servlet filter that disallows this and as such a custom servlet filter might be required that allows access to this /dwr subcontext.
Now, the second part of any AJAX interactions involves updating the UI with something interesting. Traditionally this is done by manipulating the html elements directly from javascript. While this works for simple use cases such as updating a field or displaying a bit of text, it can get tricky in situations where more complex UI are being rendered such as data grids or dynamically updated forms. I had one portlet that had many views arranged as in a typical wizard in windows and the requirements were to be able to flip between them quickly. Although this is all doable just with javascript, it is rather painful to maintain, not to mention error-prone. A much better approach would be to have html snippets ready that could be updated and slipped in where appropriate. This also has drawbacks in that the data inside the html snippets (the actual values of form elements or data grids) have to be inserted and this again involves recreating the html string in javascript.
In order to solve this problem, I thought there might perhaps be a framework that allowed UI code to be represented just like in JSP or JSTL with an appropriate mechanism to inject the data at runtime and update the view. In my search I came across Trimpath Javascript Templates (JST) that does just that. It consists of functions that can take in templates and inject a javascript object called data into it. An example of this is as follows:
<table>
{for flight in flights}
<tr>
<td>${flight.number}</td>
</tr>
{/for}
</table>
The example above is rather simple in that it is displaying a table with one column outputting all the flight numbers in the flights list. The way to do this is to add our relevant model objects in a javascript object called data and process the template. The resulting HTML can then be inserted into the innerHTML of any div or other html element as appropriate.
The templates can be any strings and can be stored anywhere. The Trimpath people recommend that they be stored in the page inside hidden textarea elements for quick access. However, for portlet that will have many views and we do not want to load all this html on the initial load, we can store these templates in template files in the backend. The trick is to use DWR to retrieve these view templates and process them as required. An additional optimization that can be done here is to keep view templates cached in a javascript object for reuse.
As I’ve discussed above, these two frameworks can make for a powerful combination when developing highly interactive AJAX portlets that require clean and easy maintenance of UI and logic.
Those who’ve been working in the outsourcing industry (on both the outsourcer and outsourcee sides) will agree that there are definitely challenges in the process that bring about a reduction in the returns from shipping tasks abroad. Those that give up prematurely tend to miss the root causes of the diminishing returns and focus more on the negative symptoms appearing at the start (and often continuing) of the game.
Those that have stuck it out will notice that the problem of communication is majorly responsible for the inefficiencies cropping up. The results from cross-cultural communication gaps are delays in product development, misinterpretation of requirements, and the seeming lack in polish and refinement characteristic, and expected, of products of the west. The challenge companies tackle now is getting this gap in communication to be as narrow as possible (eliminating communication gap is impossible even with speakers of the same language from the same background and culture) so that the returns are sizeable enough to justify continuing offshoring projects.
In communication theory, the elements in a communication “circuit”, if you will, are the sender, the receiver, the channel, the message, and the feedback. In the world of business communication, we might add the context of communication to this loop. The problems in communication arise out of barriers in each of these elements of the loop. The loop becomes as strong as the weakest link within it. If the sender and receiver are not prepared or aware of each others’ stances or backgrounds, that is a problem. If the channel (e-mail, phone, video conferencing) is not on par to continue a conversation close to a face-to-face one, then that’s another problem. If the feedback going back and forth between the two participants of a conversation isn’t effective, then the interpretation on the two sides will only diverge further.
I believe the awareness of the deficiences in the links in the communication loop is a good starting point to dealing the problem. Once we appreciate how sensitive each of these are, we may be able to adapt ourselves to better handle communication and hence achieve results in sync with expectations. Examples of this would be understanding the different priorities to channels of communication. Whereas instant messaging or a chat on the phone could work for situations where the content being exchanged is small, it would not work for situations where a lot of severe issues need to be addressed with extreme focus on detail. Another issue could be the way data is presented and the timing of that data. On more critical situations, perhaps an appointment or meeting should be arranged beforehand with a known agenda rather than interrupting the flow of work with a call or an instant message. The culture of e-mailing is another that could be improved again depending on the problems at hand. Often times we do not realize that the language or style used in presenting information is crucial to how it is going to be received and addressed.
In conclusion, there is no doubt that the issue of communication is a complex one and needs to be addressed with utmost patience and care. The myriad of ways we have to adapt our thinking and processes come with the territory of doing something so seemingly simple as offshoring a set of tasks. In the general scope of things, if we remind ourselves that change often requires some difficult adjustments and shifts in thinking, we can go forward and achieve the goals we’d set out to achieve. Outsourcing is one tough cookie to chew but people are still chewing.
Of the multitude of languages …
November 13, 2005
I’ve always been asked by people which language I write (programs) in and which one(s) I prefer. I’ve been programming in different languages since I was in the 9th grade and I have yet to develop an affinity for any particular language. Truth be told, despite having programmed in different language from early on, I’ve never quite gotten motivated to write programs at home for kicks or anything. I looked at programming as some academic activity that I’d just have to do and so preference for a particular language doesn’t quite make sense to me. For me, picking a language is more relevant when assessing the problems at hand and then choosing whatever suitable platform there is to meet the goals of that project. Other than that, I think the challenges of learning a new language are insignificant compared to the solving of various problems without having to reinvent the wheel. So far, I’ve programmed little in languages like Pascal, C, C++ and a lot more in Java and C#. That being said, I don’t think Java being my strong language necessitates that I should be blocked into programming in just that for the rest of my life. I believe in taking on any challenge head on even if it means the difference between an elegant solution and a “easier” hack solution. The modern high level object-oriented languages afford nicer solutions to the programming of high level applications using reusable components and libraries. When it comes to low level processing and speed, nothing beats C/C++ but then the price you pay is having to take care of a lot of complex stuff like memory management and threading/processes yourself.
I do like reading about the evolution of existing languages (such as in Java, C++) and the creation of new languages (C#, Comega, D, etc). They show the different paradigms of thinking through problems as well as the evolution of software and the different approaches required to deal with newer needs.
A beginning of sorts …
November 13, 2005
Having blogged casually for over a year now, I gave some thought to the prospect of blogging specifically about various technical topics. Initially I’d hesitated to start a technical blog simply because I don’t believe I have quite the level of expertise required to write or speak in detail about any particular technical phenomenon. The technical blogs that I’ve frequented so far have been owned by pioneers of the cutting edge programming technologies and were thus a natural place to turn to for a green horn such as myself to gain ideas and inspiration to start wetting my toes into these technologies that are taking the industry by storm.
I’d originally started coming across blogs through searches for solutions to small problems in C# and Java I’d encountered at work. Upon reading a few of them, I noticed that these blogs left the realm of personal blogs altogether in that they were publicized and discussed on sites and forums and considered to be the words of gurus. This relatively new phenomenon has, I think, created closer and possibly interactive (two-way) connections between application developers, new and experienced alike, and the leading pioneers of the technologies application developers build on. Among these technologies are the likes of frameworks and tools such as Spring, Tapestry, Struts, and Hibernate, to name only a few. The fact that the developers of these technologies themselves are very much alive and active (as opposed to traditional gurus who limited themselves to writing esoteric books) in the forums and communities gives application developers the encouragement that there are at least going to be experts we can turn to for help if and when we need them. This wasn’t always the case. How many times have you scoured the Internet for the way to do something simple that isn’t quite obvious within the constraints of a particular language or technology? The specification documents or references are good starts but usually do not provide specific enough guidance as to how to accomplish a specific task. Forums are full of frantic cries for help and responses that can range from a mild rebuke to go back to searching Google or to figure it out by trial and error and the occasional inaccurate and often hack solutions. These problems could otherwise could be solved elegantly if only some consideration and collaboration took place to accumulate and expose the community’s knowledge in a reliable and easier to understand manner. These “pioneer blogs”, as I see them, have afforded the developer communities just that and I think this should be inspiration for the rest of us to lend our hands in similar ways to solving problems (however small or big they may be based on our capacities) and continue to build on repositories of knowledge for the generations to come.
It is with this in mind that I embark upon this journey so that I may not only record my trials, frustrations, and triumphs, but also contribute whatever little I can to those that tread the paths I’ve tread in my professional life and academic life. I hope this spirit of collaboration and sharing ideas will help me to grow as an engineer as well as help others to grow in dimensions never before explored.