During my time as a C/C++ then Java developer, somehow I have avoided the need to write J2EE web applications. Not web enabled or web services applications, no I have somehow avoided the beast that is J2EE ( not to mention *gasp* EJB ). However the current Web 2.0 ( I read AJAX ) wave has forced me from my comfort zone ( replace 'comfort zone' with Happy Gillmore's 'Happy Place' if you like ).
*Note: when I read AJAX I read, browser based client side UI programming and not alot of buzzword happy nonsense.
I have to admit that the current wave of browser based web applications are pretty cool. I love GMail, blogger.com's interface, Google Reader, Google Calendar etc... I don't think of myself as a google fan boy, but that is another topic ( hmm... maybe I should try out 37 signals stuff like backpack ). Another reason that has forced me from my comfort zone is that fact that I have recently been evaluating technologies for my current job and taking a cursory look at the Job market again and I have come to a conclusions of sorts. People out there like these browser based applications. Something about avoid the problems of upgrades, deployment, configuration, licensing, etc... Personally I don't see their point ;) I actually like to ram my head into walls, tables, floors, etc... So I have begun a journey to acquire some of these skills and acquaint myself with those technologies that can enable them.
A brief aside, I have not been doing monolithic applications for some time now, but it is just that my container of choice is the OSGi Java container that the Eclipse platform is based on. After learning a bit more about the Spring framework and the new Spring OSGi project, I am even more impressed with OSGi as a container and enterprisey platform architecture, but this is a digression from the current topic.
Before digging into topics like AJAX, I figured I better get more acquainted with the Java Web application world in general. I know that even though frameworks exist to make development easier, but in the end you wind up needing to at least be familiar with what is going on underneath the hood. So I began to get more familiar and see what was out there.
One more point, before I tried to begin this journey, I have been acquainted with Ruby on Rails (RoR) and its convention over configuration paradigm. "Convention over configuration" is something that I had begun to use in my own work and I immediately saw its advantages over doing everything in an XML configuration file. I was suitably impressed with the ability of RoR to generate scaffolding and allow you to have an up and running web application in minutes. I am a "lazy" ( as in the good way ) kind of person and I don't like to have to perform lots of scaffolding to get get something up. Needless to say, this was something I wanted in a web application platform that I wanted to use.
So the next obvious question is, "why not use RoR?" Good question. The answer is I am a Java developer that has been working with Java for sometime now and I don't want to have to give up all my experience just to bet it on something new, if there is a viable alternative. Second part of the answer is something I don't like about Java, lack of native integration support with legacy code (JNI (Java Native Interface) is not on my christmas card list). People out there have alot written for J2EE in Java for the web, as far as I know there is no direct way to be able to leverage this legacy stuff directly in RoR. I know that the JRuby folks are getting closer to being able to run RoR through the JVM, but they are not there yet. Even when they do, the code to interact with other Java code can be awkward. This is normal, since Ruby was developed independently and has its own ideas of what a collection, array, type is and it differs at times significantly from Java. So is there a viable alternative? I think so, the Groovy language with Grails.
Groovy
Groovy (http://groovy.codehaus.org/) is a dynamic scripting language written to be friendly to those of us coming from the statically typed Java world. Just remember that Groovy is Java, just not the Java language. Java is the title of a platform that includes the JVM, libraries and the Java language. Groovy natively sits on top of the JVM and directly uses the Java libraries, so it is a Java platform language. Visit the web site to learn more and I highly recommend the "Groovy In Action" book for you to acquaint yourself with Groovy. Groovy has the great feature of being native to the Java platform and being optionally static. Now what does Grails have to do with Groovy? Simple, Groovy is the language that a Grails application is written in. So you have a choice of learning a new language that has a completely separate syntax than you are used to ( being a Java/C++ developer ) or learn a language that is more of an extension of Java and that has most ( if not all ) the advantages of the other language? Is it really an issue? To me it wasn't, if I could find a web framework like RoR to go with it.
Grails
Groovy is all fine and dandy, but it can only do so much to help with writing Web Applications. Ruby without Rails has much the same problem, that is why the Rails framework was created. Grails is the Groovy ( and indeed Java ) world's equivalent to RoR. I have been reading the "Definitive Guide to Grails" and I find the framework very interesting. You have alot of the same advantages of RoR, namely the quick development of a simple web application, standard project structure, support for writing test suites, delineation of environments ( development, production, testing ), support for switching between databases, support for the Model-View-Controller (MVC) pattern, etc... The nice thing about it all is that in the end you have a Java based web application that can be injected directly into a servlet container like Tomcat and will seamlessly interoperate with the other web applications you have already developed.
For example to create an application in Grails you type, "grails create-app". You enter in the project name and voila, the project and its scaffolding is created for you automatically. Being an Eclipse fanboy (hey if the shoe fits... yup it does...), I like the fact that the grails application scaffolding includes a .project and .classpath file that allows me to directly import the generated grails application directly into Eclipse. The cool thing is that you can type, "grails run-app" from the project directory and you have a Jetty web server up and running your web application. You can open up a web browser and see the results immediately. This is just the sort of thing that got people all excited about RoR. Another great feature is that of dynamic loading. While running your web application in Grails with "grails create-app" you can modify the code of the application and have the results displayed in your browser by just refreshing the page. This is the sort of thing that dynamically typed languages have held over Java all this time. Now Java can have this advantage, enabling quick iterative development. This is the sort of thing that in another context, that of eclipse plugin writing, led me to write the Groovy Monkey tool.
So I have been sold, hook, line and sinker. I am going to try and write some quick blog entries over the next few days as I continue to learn Grails and highlight my progress and issues.
*Btw I have no financial interests in Grails or any of the two publications I recommended ( 'Groovy in Action' and 'The Definitive Guide to Grails' ). So take my recommendations with as much salt as you like, but at least know it is not tied to any 'check in the mail' coming to me. *Sigh*
Tuesday, February 27, 2007
Friday, January 12, 2007
Install Eclipse Update Sites through a Firewall
--- Came wiffling through the eclipsey wood ---
/*
* Menu: Download > Update Site
* Script-Path: /GroovyWebUtil/monkey/UpdateSiteDownload.em
* Kudos: ERVIN
* License: EPL 1.0
* Include: /GroovyWebUtil/commons-codec-1.3.jar
* Include: /GroovyWebUtil/commons-httpclient-3.0.1.jar
* Include: /GroovyWebUtil/commons-logging-1.0.3.jar
* Include-Bundle: org.apache.ant
*/
import java.io.*
import java.net.*
import org.apache.commons.httpclient.*
import org.apache.commons.httpclient.auth.*
import org.apache.commons.httpclient.methods.*
import org.apache.commons.io.*
import org.apache.commons.lang.*
import org.eclipse.core.resources.*
import org.eclipse.core.runtime.*
// Set these following 8 parameters
def featureName = 'GroovyEclipsePlugin'
def baseURL = 'http://dist.codehaus.org/groovy/distributions/update/'
def siteURL = baseURL + 'site.xml'
def baseDir = 'c:/plugins/' + featureName + '/eclipse/'
def proxyHost = 'xxxx'
def proxyPort = xx
def proxyUser = 'xxxx'
def proxyPassword = 'xxxx'
def client = new HttpClient()
client.params.setParameter( CredentialsProvider.PROVIDER, this )
client.hostConfiguration.setProxy( proxyHost, proxyPort )
FileUtils.forceMkdir( new File( baseDir ) )
FileUtils.touch( new File( baseDir + '.eclipseextension' ) )
def method = new GetMethod( siteURL )
client.executeMethod( method )
out.println 'status: ' + method.statusText + ' -> ' + siteURL
def input = method.responseBodyAsStream
def siteXML = new XmlSlurper().parse( input )
def features = siteXML.feature
def featureURLs = [ : ]
def versionMap = [ : ]
features.each
{ feature ->
if( !versionMap.containsKey( feature.@id.text() ) )
versionMap[ feature.@id.text() ] = feature.@version.text()
if( versionMap[ feature.@id.text() ].compareTo( feature.@version.text() ) > 0 )
return
featureURLs[ feature.@id.text() ] = feature.@url
}
def ant = new AntBuilder()
def plugins = []
featureURLs.values().each
{ featureURL ->
if( monitor.isCanceled() )
return
def newURL = new URL( baseURL + featureURL )
def featureFile = baseDir + featureURL
def destDir = StringUtils.substringBeforeLast( featureFile, '.' )
FileUtils.forceMkdir( new File( destDir ) )
FileUtils.copyURLToFile( newURL, new File( featureFile ) )
ant.unzip( src: featureFile, dest: destDir )
ant.delete( file: featureFile )
def featureXMLText = new File( destDir + '/feature.xml' ).text
def featureXML = new XmlSlurper().parseText( featureXMLText )
featureXML.plugin.depthFirst().collect{ plugins.add( it ) }
}
monitor.beginTask( 'Starting downloads', plugins.size() + 1 )
plugins.each
{ plugin ->
if( monitor.isCanceled() )
return
def pluginJar = "${plugin.@id}_${plugin.@version}.jar"
def newURL = new URL( baseURL + 'plugins/' + pluginJar )
def pluginFile = baseDir + 'plugins/' + pluginJar
def destDir = StringUtils.substringBeforeLast( pluginFile, '.' )
FileUtils.forceMkdir( new File( destDir ) )
if( new File( pluginFile ).exists() )
return
FileUtils.copyURLToFile( newURL, new File( pluginFile ) )
if( plugin.@unpack.text().trim().toLowerCase() != 'false' )
{
ant.unzip( src: pluginFile, dest: destDir )
ant.delete( file: pluginFile )
}
}
--- And burbled as it ran! ---
--- Came wiffling through the eclipsey wood ---
/*
* Menu: Download > Update Site
* Script-Path: /GroovyMonkeyScripts/monkey/UpdateSiteDownload.gm
* Kudos: ERVIN
* License: EPL 1.0
* DOM: http://groovy-monkey.sourceforge.net/update/plugins/net.sf.groovyMonkey.dom
* Include: /GroovyMonkeyScripts/commons-codec-1.3.jar
* Include: /GroovyMonkeyScripts/commons-httpclient-3.0.1.jar
* Include: /GroovyMonkeyScripts/commons-logging-1.1.jar
* Include-Bundle: org.apache.ant
*/
import java.io.*
import java.net.*
import org.apache.commons.httpclient.*
import org.apache.commons.httpclient.auth.*
import org.apache.commons.httpclient.methods.*
import org.apache.commons.io.*
import org.apache.commons.lang.*
import org.eclipse.core.resources.*
import org.eclipse.core.runtime.*
// Set these following 8 parameters
def featureName = 'GroovyEclipsePlugin'
def baseURL = 'http://dist.codehaus.org/groovy/distributions/update/'
def siteURL = baseURL + 'site.xml'
def baseDir = 'c:/plugins/' + featureName + '/eclipse/'
def proxyHost = 'xxxx'
def proxyPort = xx
def proxyUser = 'xxxx'
def proxyPassword = 'xxxx'
def client = new HttpClient()
client.params.setParameter( CredentialsProvider.PROVIDER, this )
client.hostConfiguration.setProxy( proxyHost, proxyPort )
FileUtils.forceMkdir( new File( baseDir ) )
FileUtils.touch( new File( baseDir + '.eclipseextension' ) )
def method = new GetMethod( siteURL )
client.executeMethod( method )
out.println 'status: ' + method.statusText + ' -> ' + siteURL
def input = method.responseBodyAsStream
def siteXML = new XmlSlurper().parse( input )
def features = siteXML.feature
def featureURLs = [ : ]
def versionMap = [ : ]
features.each
{ feature ->
if( !versionMap.containsKey( feature.@id.text() ) )
versionMap[ feature.@id.text() ] = feature.@version.text()
if( versionMap[ feature.@id.text() ].compareTo( feature.@version.text() ) > 0 )
return
featureURLs[ feature.@id.text() ] = feature.@url
}
def ant = new AntBuilder()
def plugins = []
featureURLs.values().each
{ featureURL ->
if( monitor.isCanceled() )
return
def newURL = new URL( baseURL + featureURL )
def featureFile = baseDir + featureURL
def destDir = StringUtils.substringBeforeLast( featureFile, '.' )
FileUtils.forceMkdir( new File( destDir ) )
FileUtils.copyURLToFile( newURL, new File( featureFile ) )
ant.unzip( src: featureFile, dest: destDir )
ant.delete( file: featureFile )
def featureXMLText = new File( destDir + '/feature.xml' ).text
def featureXML = new XmlSlurper().parseText( featureXMLText )
featureXML.plugin.depthFirst().collect{ plugins.add( it ) }
}
monitor.beginTask( 'Starting downloads', plugins.size() + 1 )
plugins.each
{ plugin ->
if( monitor.isCanceled() )
return
def pluginJar = "${plugin.@id}_${plugin.@version}.jar"
def newURL = new URL( baseURL + 'plugins/' + pluginJar )
def pluginFile = baseDir + 'plugins/' + pluginJar
def destDir = StringUtils.substringBeforeLast( pluginFile, '.' )
if( new File( pluginFile ).exists() )
return
FileUtils.copyURLToFile( newURL, new File( pluginFile ) )
out.println "${plugin.@id}: unpack=${plugin.@unpack.text()}"
if( plugin.@unpack.text().trim().toLowerCase() == 'false' )
return
FileUtils.forceMkdir( new File( destDir ) )
ant.unzip( src: pluginFile, dest: destDir )
ant.delete( file: pluginFile )
}
--- And burbled as it ran! ---
Want to be able to download eclipse plugins, but the firewall wont let you?
Having trouble getting the eclipse update mechanism to tunnel through the firewall, but port 80 is open through http?
If you have Groovy Monkey installed and include the commons-codec-1.3.jar, commons-httpclient-3.0.1.jar and commons-logging-1.0.3.jar libraries in your workspace, use the script above. Define the 8 parameters and the script should download the update package from the url that the update manager should connect to. The script then packages it as the appropriate set of plugins ( zipped or unzipped ) based on the feature.xml and then deploys it to a directory that you can define and creates an extension location that Eclipse can directly import.
In the script above I downloaded the Groovy Eclipse plugin from the update site and had it packaged into the /plugins/GroovyEclipse/eclipse directory as an extension location. I like to separate my plugins like this. The last step is after the script runs successfully goto "Help -> Software Updates -> Manage Configuration" and open the manage configuration dialog. Right click on the root node "Eclipse SDK" and select "Add -> Extension Location". Navigate to the location where the plugin was installed, in the above case /plugins/GroovyEclipse/eclipse, and then click ok. Eclipse will install the plugin and probably ask to restart. You are done...
Labels:
Eclipse,
Groovy,
GroovyMonkey,
Monkey
Tuesday, December 26, 2006
Version 0.4.0 is released
I have released the latest version of Groovy Monkey with the following new features:
I am also in the process of merging Groovy Monkey with the original Eclipse Monkey, so future work maybe accomplished over there.
Version 0.4.0 - December 24, 2006
- Added autocomplete for binding variables.
- Added method autocompletion for bound variables.
- Now can publish to clipboard directly from the editor.
- Added a "Save Script To" dialog to allow the user to select where in their workspace they want the script written.
I am also in the process of merging Groovy Monkey with the original Eclipse Monkey, so future work maybe accomplished over there.
Labels:
Eclipse,
Groovy,
GroovyMonkey
Tuesday, December 19, 2006
Quickly remove unwanted markers in your workspace.
I have been asked, "Groovy Monkey why?" Now there are the default answers of API exploration, Eclipse Automation and rapid prototyping, however, now I have a new one: "You think someone will bother to write a plugin to do that?" The following example highlights this feature.
Here is a quick script written whilest I was debugging the Groovy Eclipse Plugin. The problem I had was that the plugin left some markers lying around that I don't want to see anymore.
So you can use this script to parse through your Eclipse workspace and find all the problem markers and then choose to delete those that don't apply anymore. I think it is pretty useful when you are working on plugins or if you downloaded a particularly buggy plugin. Sure does beat shutting down Eclipse, then opening up the $workspace/.metadata/org.eclipse.core.resources/.projects/$projectname/ and then manually deleting any .markers files you find.
To import the script into Eclipse follow the following steps.
First you must have installed Groovy Monkey.
Secondly, then you must select all the text below ( starting with '--- Came wiffling...' and copy it into your clipboard on your browser (Ctrl-C usually works).
Now goto eclipse and under the Groovy Monkey menu select 'Paste New Script'.
Voila it will be incorporated into your workspace and can be run as 'Groovy Monkey > Remove Markers'. Enjoy.
Here is a quick script written whilest I was debugging the Groovy Eclipse Plugin. The problem I had was that the plugin left some markers lying around that I don't want to see anymore.
So you can use this script to parse through your Eclipse workspace and find all the problem markers and then choose to delete those that don't apply anymore. I think it is pretty useful when you are working on plugins or if you downloaded a particularly buggy plugin. Sure does beat shutting down Eclipse, then opening up the $workspace/.metadata/org.eclipse.core.resources/.projects/$projectname/ and then manually deleting any .markers files you find.
To import the script into Eclipse follow the following steps.
First you must have installed Groovy Monkey.
Secondly, then you must select all the text below ( starting with '--- Came wiffling...' and copy it into your clipboard on your browser (Ctrl-C usually works).
Now goto eclipse and under the Groovy Monkey menu select 'Paste New Script'.
Voila it will be incorporated into your workspace and can be run as 'Groovy Monkey > Remove Markers'. Enjoy.
--- Came wiffling through the eclipsey wood ---
/*
* Menu: Remove Markers
* Script-Path: /GroovyMonkeyScripts/monkey/removeMarkers.gm
* Kudos: ERVIN
* License: EPL 1.0
* DOM: http://groovy-monkey.sourceforge.net/update/plugins/net.sf.groovyMonkey.dom
*/
import org.eclipse.core.resources.*
out.clear()
workspace.root.projects.each
{ project ->
out.println "${project.name}"
project.findMarkers( null, true, IResource.DEPTH_INFINITE ).each
{ marker ->
out.println " ** ${marker.type} ${marker.id} ${marker.attributes}"
if( marker.type == 'org.codehaus.groovy.eclipse.groovyFailure' )
marker.delete()
}
}
--- And burbled as it ran! ---
Labels:
Eclipse,
Groovy,
GroovyMonkey
Monday, September 11, 2006
Version 0.3.0 of Groovy Monkey released
I am just putting all the packaging in place for the latest version of Groovy Monkey, version 0.3.0. By the way, I am not putting a whole lot of meaning behind the version numbers, 0.2.0 was chosen before since it was originally a port of Eclipse Monkey and it was at version 0.1.5 or something. The following is noteworthy:
Version 0.3.0 - September 11, 2006
- Changed the Groovy Monkey default project name to GroovyMonkeyScripts as per issue: [ 1536760 ] Change GroovyMonkeyExamples to GroovyMonkeyScripts
- Added an Include-Bundle dialog to the editor context menu, to the Package Explorer view and Navigator.
- Added Include and Include-Bundle dialogs to Groovy Editor context menu command set.
- Added a Java search, modeled on the PDE search, to the outline view to look for all the classes exposed from an included bundle in the set of exported packages. So if your 'External Plug-in Libraries' project is setup, you should see the classes.
- Added a Script-Path: metadata tag that is automatically maintained by Groovy Monkey, it is set to the workspace path of the script.
- The Script Outline view now has menu commands to switch between Flat/Hierarchical views of the binding.
- There are now error markers signifying some command errors with script metadata and some quick fixes to assist.
- There is now some content assist on the Script Metadata tags.
- A new submenu of the top level 'Groovy Monkey' has been added called 'Edit Script'. The Edit Script submenu reflects the top menu, but instead of launching the scripts, it opens the editor for you.
- Added Hippie completion to the editor.
- Added ability to map dom vars to different names for the local script, enables solution for variable name conflicts between DOM plugins.
Labels:
Eclipse,
Groovy,
GroovyMonkey
Subscribe to:
Posts (Atom)
