Thursday, March 08, 2007

Add Groovy to your Eclipse Plugin Projects

I have begun some basic work on the Grails Eclipse plugin that I outlined in a proposal in a previous post. One of the features I want to highlight will be the fact that I want the plugin to be almost exclusively written in Groovy instead of Java.

As I start work on the plugin, I want to highlight a feature that I will hopefully add to the Groovy Eclipse Plugin in the real near future, Groovy PDE Build support. If you install the Groovy Eclipse Plugin ( I think the version currently in Head/Trunk is better than the one on the update site ), you will find that your development for the most part goes smoothly, except for when you start using Groovy to write your Eclipse Plugins. The issue is that the PDE Builder doesn't know, and probably doesn't want to know, about the Groovy code and its need to be compiled with the Groovy compiler. So how do you deal with this?

One way is to parallel the work of the Eclipse PDE Build team and write your own scripts that can interpret the build.properties file to export your plugin yourself. This can make you proud and think you are a real programmer, except that why in the heck do you want to repeat something that has already been done?

Another way is to generate the build.xml file, click the custom build option on the plugin and maintain the ant build file manually. Do I need to go into the obvious problems and pain with this option? If you like pain, reading ant XML scripts, pain, deciphering the incredibly ( but probably necessary ) complex PDE build process, pain, keeping your Ant XML file synchronized to changes in your project manually, and yet more pain, go ahead. I wont stop you, for the rest of us I am going to cover the next, and I believe, better option.

One side note, I am very familiar with the pain that I described above, I wrote a series of Groovy scripts to build our products, as per the first option. Pretty cool and better than the second option, but it really was a source of pain and, as I will now show you, unnecessary work.

The final option I give you, with an example, is what I think to be the best option. In fact, I wish I knew of it before on previous Eclipse based projects. As of Eclipse 3.2, you have the ability to specify a custom callbacks XML file.

To add Groovy PDE Build support to your plugin project, first you must install the Groovy Eclipse plugin and enable the groovy nature for your project. Deployment of the groovy libraries into your plugin for installation is another topic for another time.

Afterwards goto your Eclipse installation directory and open up the plugins directory. Goto the org.eclipse.pde.build plugin installation directory and look in the templates/plugins subdirectory. You will see there a template called customBuildCallbacks.xml, import this into your project.

Now open up your build.properties file and add a property called customBuildCallbacks like the following example:

customBuildCallbacks = customBuildCallbacks.xml

This means that the build will now reference a callback Ant Build script in my project called customBuildCallbacks.xml in the root of my project. You could prepend a project relative path to the file name to place the file somewhere else if you choose.

The next step I like to do is to right click the manifest.mf(plugin.xml) file and ask the PDE to generate a build.xml file. Now I am not going to keep the build.xml file around very long nor its javaCompiler args file. I am going to use it to extract the targets that will be called in the callback ant script and to find out the name of the classpath reference that will be used.

Below is an example file from the plugin I am currently working on.

<subant antfile="${customBuildCallbacks}" target="pre.@dot" failonerror="false" buildpath=".">
<property name="source.folder1" value="src/"/>
<property name="target.folder" value="${temp.folder}/@dot.bin"/>
<reference refid="@dot.classpath"/>
</subant>
<!-- compile the source code -->
<javac destdir="${temp.folder}/@dot.bin" failonerror="${javacFailOnError}" verbose="${javacVerbose}" debug="${javacDebugInfo}" includeAntRuntime="no" bootclasspath="${bundleBootClasspath}" source="${bundleJavacSource}" target="${bundleJavacTarget}" >
<compilerarg line="${compilerArg}" compiler="${build.compiler}"/>
<classpath refid="@dot.classpath" />
<src path="src/" />
<compilerarg value="@${basedir}/javaCompiler...args" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
<compilerarg line="-log '${temp.folder}/@dot.bin${logExtension}'" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
</javac>
<!-- Copy necessary resources -->
<copy todir="${temp.folder}/@dot.bin" failonerror="true" overwrite="false">
<fileset dir="src/" excludes="**/*.java, **/package.htm*" />
</copy>
<subant antfile="${customBuildCallbacks}" target="post.compile.@dot" failonerror="false" buildpath=".">
<property name="source.folder1" value="src/"/>
<property name="target.folder" value="${temp.folder}/@dot.bin"/>
<reference refid="@dot.classpath"/>
</subant>


There are two subant tasks that are of interest one before the javac task and one after. You can overload one or both in your callbacks ant script to allow the groovy builder to run before, after or before and after the java compiler. The important thing here is that the target name and classpath reference in your callbacks script must match.



Here below is an example from my current plugin project.



<target name="pre.@dot">
</target>

<!-- ===================================================================== -->
<!-- Steps to do during the compilation target <name>, after the compile -->
<!-- but before jaring. Substitute "name" with the name of the compilation-->
<!-- target, eg @dot -->
<!-- Available parameters : -->
<!-- source.foldern : n = 1 ... N, the source folders -->
<!-- target.folder : where the results of the compilation go -->
<!-- <name>.classpath : name = name of the compilation target. A -->
<!-- reference to the classpath structure. -->
<!-- ===================================================================== -->
<target name="post.compile.@dot">
<path id="org.codehaus.groovy.eclipse.libs">
<fileset dir="../org.codehaus.grails.eclipse/grails-home/lib">
<include name="**/*.jar"/>
</fileset>
</path>
<taskdef name="groovy"
classname="org.codehaus.groovy.ant.Groovy"
classpathref="org.codehaus.groovy.eclipse.libs"/>
<taskdef name="groovyc"
classname="org.codehaus.groovy.ant.Groovyc"
classpathref="org.codehaus.groovy.eclipse.libs"/>
<delete>
<fileset dir="${target.folder}" includes="**/*.groovy"/>
</delete>
<groovy classpathref="@dot.classpath">
def classpathString = task.classpath.list().toList().findAll{ new File( "$it" ).exists() }.join( File.pathSeparator )
ant.groovyc( srcdir: properties.'source.folder1',
destdir: properties.'target.folder',
stacktrace:'true',
classpath: classpathString )
</groovy>
</target>



The important things to notice are that the targets are called pre.@dot and post.compile.@dot which were derived from the generated ant build script and could be derived from your build.properties file. The next thing to notice is the classpath called 'org.codehaus.groovy.eclipse.libs' that points to a directory and slurps in all available jar files. This is done to locate the groovy library and therefore the groovy and groovyc ant tasks. You must set the path, either relative to the workspace or hardcoded from your file system. The last thing to notice is the use of the sourceN.folder properties, if you have more than one source folder that is being compiled into your plugin, then you must make allowance for it. If you are not sure, go back to the generated build.xml, it will tell you since it will set those properties before making the subant call to your customBuildCallbacks.xml script.


Conclusion


What is the point of all this? Well simply put, once you have made these modifications, you can write groovy code in your plugin and have the Eclipse PDE Builder/Exporter compile your groovy code along with your bundle with no muss or fuss. This functionality works if you are exporting a plugin, or as part of a feature or as part of an update site. Cool eh?



One last point, since most of this is rather rote cut and paste, I am looking to enhance the Groovy Eclipse Plugin to handle this for you. Hopefully it should be part of the next official release on the update site.

Tuesday, March 06, 2007

Grails Eclipse IDE Support

I knew that the idea of an IDE plugin to support Grails could not be new. So I am going to post the contents a nice little "IDE Integration Wish List" from the grails wiki site. I am then going to make a proposal for what I see the path of a Grails Eclipse plugin would take. Comments are more than welcome.


IDE Wish List (from grails.org)
Below are the features that would be great to have from a Grails IDE:

  • Wizards to create Grails artifacts like controllers/domain objects and so on. Unlike Rails, Grails doesn't do any background configuration with its command line tools so these can merely be simple wizards
  • Running a Grails server embedded in the IDE and being able to step debug the application. Groovy provides all the information in the classes necessary to enable step debugging of Groovy code
  • Code navigation with keyboard shotcuts and CTRL+click between Grails artifacts like controllers domain classes etc.
  • Code completion for things like dynamic finders and persistent methods like save/delete/findAll/findBy* on domain classes
  • Auto-completion of Grails tags in GSPs
  • Integration of an embedded Grails console to be able to execute arbitrary scripts against a running application
  • Being able to right-click execute Grails unit tests and get green/red bars etc.
  • Being able to right-click on a Grails project and execute all unit tests
  • Being able to right-click on a domain class and click generate to generate a controller and views for CRUD
  • Better editor support for groovy files. This means autocompletion and so on.
  • Special outline views for Domain-Classes, Controllers and Views
    Graphical editor for Domain Classes, with a UML-like or ER-like view
  • The IDE should hook into Grails' upcoming plug-in architecture to be able to do things like auto-find new executable scripts, download and install new plug-ins etc.
  • Integration of every Servlet-Container to test the Grails-App. The best solution were intergration into webtools
  • XP Refactor support (e.g. rename methods/groovy file names and cascade changes to all dependencies)

Proposal
I would like to start by taking the Grails application and embedding it within a set of Eclipse plugins and then have Eclipse plugins to be able to run directly from the workbench ( via right click options ) the command line commands directly. This would mean that you would not have to install Grails seperately, kinda like Eclipse handles ant.

After that I would like to begin integrating the Groovy Eclipse plugin into the mix. I think that the Groovy Eclipse plugin should be included seperately from the Grails plugin to avoid issues of differing Groovy versions ( that Grails could require different versions from the main Groovy distribution ) and to avoid the overhead of installing all the Grails libraries along with the Groovy Eclipse plugin. Of course, there would be lots and lots of overlap and we should be able to leverage any new improvements in the Groovy plugin quickly. The Groovy Eclipse plugin with its editor and outline view would be the basis for adding more support for Grails.

After the Groovy Eclipse plugin functionality is added, the fun can really begin. As I mentioned in a previous post, convention over configuration would allow us to inject suggestions to method completion. A first target would be the Data Source configuration files, a second would be the Domain classes, and so forth.

A related issue would be to find an open source JSP Editor project that would be willing to partner with us to help develop the GSP Editor. If an acceptable one is not found, then one will have to be fabricated, probably based on a previously existing XML editor.

I think this could be very useful ( i.e. cool ) and since we could leverage already existing tools, we could have something to show rather quickly and have a nice evolutionary path to add new features and functions a little bit at a time.

I would love comments on this proposal.

Convention over Configuration == Eclipse IDE completion support for Grails?

As I am going through the "Definitive Guide to Grails", I can definitely say that for the most part things are going well. I wish that the dynamic update feature would work, but other than that things are going well.

One thing that has been hitting me like a pile of bricks, is Grails' use of injection to put properties and methods onto an object without it needing to extend a base class. This is all fine and dandy, but who can remember all those extensions easily for like a domain class? I know the IDE can.

As work has been progressing on method completion on the Groovy Eclipse plugin ( great work Ed ), it occured to me that adding additional completion options based on the fact that the project is a grails project should not be very hard, not hard at all. In fact, I did something similar in Groovy Monkey to add autocompletion and elements in the outline view based on what the script's binding was. How cool would that be, to not have to remember the domain's class' get, what actions are injected automatically into a controller, to perhaps provide some assistance to using the findBy* methods?

In fact, the way I think about it, using conventions is a bit like having static type information around. And if you have some equivalent of static type information, don't autocompletion and other IDE goodies follow?

I are not Stoopid


StupidTester.com says I'm 4% Stupid! How stupid are you? Click Here!

I just wasted a few minutes of my life to fill out the stoopid test, I wonder if that means that their test is a bit faulty??

Tuesday, February 27, 2007

Why dig into Grails?

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*

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...