Skip to content
Skip to breadcrumbs
Skip to header menu
Skip to action menu
Skip to quick search
Quick Search
Browse
Pages
Blog
Labels
Attachments
Mail
Advanced
What’s New
Space Directory
Feed Builder
Keyboard Shortcuts
Confluence Gadgets
Log In
Dashboard
Groovy
Copy Page
You are not logged in. Any changes you make will be marked as
anonymous
. You may want to
Log In
if you already have an account. You can also
Sign Up
for a new account.
This page is being edited by
.
Paragraph
Paragraph
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
Preformatted
Quote
Bold
Italic
Underline
More colours
Strikethrough
Subscript
Superscript
Monospace
Clear Formatting
Bullet list
Numbered list
Outdent
Indent
Align left
Align center
Align right
Link
Table
Insert
Insert Content
Image
Link
Attachment
Symbol
Emoticon
Wiki Markup
Horizontal rule
tinymce.confluence.insert_menu.macro_desc
Info
JIRA Issue
Status
Gallery
Tasklist
Table of Contents
Other Macros
Page Layout
No Layout
Two column (simple)
Two column (simple, left sidebar)
Two column (simple, right sidebar)
Three column (simple)
Two column
Two column (left sidebar)
Two column (right sidebar)
Three column
Three column (left and right sidebars)
Undo
Redo
Find/Replace
Keyboard Shortcuts Help
<p><table class="wysiwyg-macro" data-macro-name="excerpt" data-macro-parameters="atlassian-macro-output-type=BLOCK|hidden=true" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2V4Y2VycHQ6aGlkZGVuPXRydWV8YXRsYXNzaWFuLW1hY3JvLW91dHB1dC10eXBlPUJMT0NLfQ&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="RICH_TEXT"><tr><td class="wysiwyg-macro-body"><p>framework for Groovy-based WinNT (Windows) Services </p></td></tr></table></p> <h1>Introduction</h1> <p><strong>Gosh</strong> provides an alternate way to run command-line <strong>Groovy</strong> scripts, as well as a simplified way to write <strong>Windows Services</strong> (<strong>WinNT Services</strong>) using <strong>Groovy</strong>. <strong>Gosh</strong> treats scripts the same, whether they are run from the command-line or as a service (including bindings). You can debug a service by running it from the command-line, and you can also run standard command-line <strong>Groovy</strong> scripts. There is very little difference between a <strong>Groovy</strong> script that is intended to be run as a <strong>Windows Service</strong> and any other <strong>Groovy</strong> script.</p> <p><strong>Gosh</strong> uses <a href="http://javaservice.objectweb.org">JavaService</a> to do the "heavy lifting" of running a <strong>Windows Service</strong>. <strong>Gosh</strong> provides the framework that integrates command-line and service calls with <strong>Groovy</strong>, and a utility to configure <strong>JavaService</strong>. The end result is something that is a lot easier to develop with, and ultimately a lot easier to maintain, than <strong>Windows Services</strong> based on pure <strong>Java</strong> using <strong>JavaService</strong>.</p> <p>This project has been under development since the middle of 2007, but it still should be considered beta software. Some of the details documented here are likely to change over time. We will, of course, attempt to maintain backward-compatibility as much as possible going forward. As of this writing, the following items still need to be addressed (these will be documented in Jira eventually):</p> <ul> <li>Need an installer. Manual setup is still a little more complex than I would like.</li> <li>Should use a native runner for command-line. Currently uses a batch file.</li> <li>Setting up a new <strong>Windows Service</strong> requires a batch file. Should support either a GUI or <strong>Groovy</strong> script.</li> <li>Classloader structure needs peer review (has proven to work well in testing).</li> <li>Dynamic-loading design (including folder structure conventions) needs peer review. Folder structure may still change.</li> <li>Dynamic loading of <strong>DLLs</strong> is still experimental at this point - has not been proven in non-sun JVMs.</li> <li>Better support for advanced logging. Currently only supports simple <em>stdout</em> and <em>stderr</em> capture to file.</li> <li><strong>Gosh</strong> uses an older version of <strong>JavaService.exe</strong> to run <strong>Windows Services</strong>. Needs to be updated and tested. Proven stable through <strong>Java 6u3</strong>.</li> <li>Need to take a look at <strong>JavaServiceWrapper</strong> from TanukiSoftware as a possible replacement for <strong>JavaService</strong>, since it seems to have more features and also supports <strong>Unix</strong> daemons.</li> <li>Need to find a new name for the project. Can anyone do better than "<strong>Gosh</strong>?"<br class="atl-forced-newline" /> <table class="wysiwyg-macro" data-macro-name="warning" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e3dhcm5pbmd9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="RICH_TEXT"><tr><td class="wysiwyg-macro-body"> <p>When installed, <strong>Gosh</strong> takes over as the default command-line runner for <strong>Groovy</strong>. This may break existing code.</p></td></tr></table></li> </ul> <h1>Requirements</h1> <p>The following is required to run <strong>Gosh</strong>:</p> <ul> <li>32-bit <strong>Windows</strong>/<strong>Java</strong> (<strong>x86</strong> architecture) - <strong>x64</strong> and <strong>IA-64</strong> architectures are not supported</li> <li><strong>Java 1.5</strong> or higher</li> <li><strong>Groovy 1.5</strong> or higher (included in download)</li> </ul> <h1>Installation</h1> <p>Download the project archive and extract the files.</p> <ul> <li><img class="emoticon emoticon-thumbs-up" data-emoticon-name="thumbs-up" border="0" src="/s/en_GB/3278/15/_/images/icons/emoticons/thumbs_up.png" alt="(thumbs up)" title="(thumbs up)" /> <a class="confluence-link unresolved" data-filename="gosh-0.1.zip" data-linked-resource-default-alias="gosh-0.1.zip" href="#">gosh-0.1.zip</a> Build 3 (1/3/2008) - Complete build including binaries, source, documentation, and examples.</li> </ul> <p>Follow the installation instructions in the <strong>.\docs\Groovy Gosh Users Guide.pdf</strong> file. <br class="atl-forced-newline" /></p> <h1>Building from Source</h1> <p> Everything you need (except for ant) to build <strong>Gosh</strong> is included in the download. Navigate to <strong>.\gosh\build</strong> and run <strong>make.bat</strong>. </p> <h1>Project Structure</h1> <p>The <strong>Gosh</strong> project structure is designed to accommodate complex projects. This may include projects containing multiple <strong>JAR</strong> libraries and <strong>JNI DLLs</strong>, where different versions of the same library may exist on one machine. <strong>Gosh</strong> also supports convenient programmable runtime configuration using - drumroll please - a <strong>Groovy</strong> script. </p> <p>One of the key differences between <strong>Gosh</strong> and the <strong>Groovy</strong> command-line tools is the emphasis on local, dynamic (runtime) project configuration. The <strong>Gosh</strong> project model follows a convention similar to what you would see in an application server, like a <strong>Tomcat</strong> web application. The standard <strong>Groovy</strong> command-line tools use a global configuration file that applies to all scripts. Although these tools support dynamically changing the classpath, the support is not obvious and somewhat awkward. </p> <p>Conversely, in <strong>Gosh</strong>, there is no global configuration at all. <strong>JAR</strong> files (and also <strong>DLLs</strong>) are local to the project, and are loaded dynamically. <strong>Gosh</strong> also supports a local configuration script, written in <strong>Groovy</strong>, that lets you conditionally define external dependencies. This makes it easy to use different library versions in different projects on the same machine, something which <strong>Groovy</strong> isn't particularly good at at them moment. It also makes it almost foolproof to distribute an entire <strong>Groovy</strong>-based application to different machines (<strong>xcopy</strong> or <strong>zip</strong> the project).</p> <p>Note that you can run multiple scripts from a single <strong>Gosh</strong> project. That includes <strong>Windows Services</strong>. So you can define, for example, 5 <strong>Windows Services</strong> and 20 utility scripts in the same project, all using the same set of <strong>JAR</strong> files and <strong>DLLs</strong>. </p> <p>A <strong>Gosh</strong> project consists of a root folder containing the following:</p> <ul> <li>Uncompiled <strong>Groovy</strong> scripts, class files, properties files, and other resources. </li> <li>(optional) A <strong>.\GROOVY-INF</strong> folder, containing any of the following: <ul> <li>(optional) A <strong>.\lib</strong> folder containing <strong>JAR</strong> files. These will automatically be added to the classloader.</li> <li>(optional) A <strong>.\bin</strong> folder containing additional Windows <strong>*.DLL</strong> files. This path is added to the beginning of the <strong>java.library.path</strong>, so <strong>DLLs</strong> in this folder override other <strong>DLLs</strong> on the local machine.</li> <li>(optional) A <strong>.\config.groovy</strong> script. This lets you do any additional configuration, like loading external <strong>JAR</strong> files or setting up logging.</li> </ul> </li> </ul> <p>When you run a <strong>Groovy</strong> script using <strong>Gosh</strong>, this is what happens:</p> <ol> <li><strong>Gosh</strong> "discovers" the project root folder. <strong>Gosh</strong> searches upwards from the current folder, looking for a <strong>.\GROOVY-INF</strong> folder. The project root is handled by a single instance of <strong>GroovyClassLoader</strong>. <ol> <li>If it is found, the folder containing it becomes the project root. This affects the assumed package hierarchy of the project.</li> <li>If it is not found, the folder containing the script is assumed to be the project root. Note that this means you can't reliably run <strong>Groovy</strong> scripts from within packages unless you define <strong>.\GROOVY-INF</strong>!</li> </ol> </li> <li>If it exists, <strong>Gosh</strong> loads all the <strong>JAR</strong> files in <strong>.\GROOVY-INF\lib</strong> into the system classloader.</li> <li>If it exists, <strong>Gosh</strong> adds the <strong>.\GROOVY-INF\bin</strong> folder to the <strong>java.library.path</strong>.</li> <li>If it exists, <strong>Gosh</strong> runs the <strong>.\GROOVY-INF\config.groovy</strong> script (<strong>config.groovy</strong> is compiled and cached, so this step actually costs very little).</li> <li>Finally, <strong>Gosh</strong> runs your script. <br class="atl-forced-newline" /></li> </ol> <p>Although it looks like a lot is going on here, the logic is actually very streamlined and fast. We've taken great pains to minimize the startup time, and the performance is generally acceptable.</p> <h1>Configuring a Windows Service</h1> <p>You can initially configure a <strong>Windows Service</strong> using a simple <strong>DOS</strong> batch file. Additional configuration is accomplished using Windows administration tools and by directly editing the <strong>Windows Registry</strong>. The tools are a little crude still, but none of this is very difficult. The documentation here should give you a clear understanding of what is necessary to configure and maintain a <strong>Gosh</strong>-based <strong>Windows Service</strong>.</p> <h2>1. Initial Configuration: DOS Batch File</h2> <p>To create (or recreate) a Windows Service, you will need to define a batch file. The batch file will call another batch file, <strong>goshservice.bat</strong>, with a set of parameters, as in the code example below. <strong>Goshservice.bat</strong> wraps the call to <strong>JavaService.exe</strong>, which requires relatively complex command line syntax. </p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> SET JAVASERVICE_STUB="C:\myapp\bin\MyService.exe" SET SERVICE_NAME="My Service" SET GROOVY_SCRIPT="C:\myapp\MyService.groovy" SET LOGS_FOLDER="C:\myapp\logs\myservice" C:\apps\gosh\javaservice\goshservice.bat %JAVASERVICE_STUB% %SERVICE_NAME% %GROOVY_SCRIPT% %LOGS_FOLDER% </pre></td></tr></table> <p>The parameters you pass to <strong>goshservice.bat</strong> are defined as follows:</p> <table class="confluenceTable"><tbody> <tr> <th class="confluenceTh"><p> Parameter </p></th> <th class="confluenceTh"><p> Description </p></th> </tr> <tr> <td class="confluenceTd"><p> JAVASERVICE_STUB </p></td> <td class="confluenceTd"><p> Each service needs a renamed copy of JavaService.exe to function. The batch file makes a copy for you, in the location you specify, and uses it to run the service. </p></td> </tr> <tr> <td class="confluenceTd"><p> SERVICE_NAME </p></td> <td class="confluenceTd"><p> The name of the service. Must be unique. </p></td> </tr> <tr> <td class="confluenceTd"><p> GROOVY_SCRIPT </p></td> <td class="confluenceTd"><p> The groovy script to run as a service. </p></td> </tr> <tr> <td class="confluenceTd"><p> LOGS_FOLDER </p></td> <td class="confluenceTd"><p> Standard out and standard err streams will be written to this folder, as files. Note that each service needs a unique folder! </p></td> </tr> </tbody></table> <p>After you run your batch file, the new service will be accessible for additional configuration from the Windows <strong>Services</strong> tool. You can rerun the batch file with different parameters, but remember that you will have to redo the manual configuration steps each time.</p> <h2>2. Additional Configuration: Windows Tools</h2> <p>Most <strong>Windows Services</strong> require some additional setup. Open the <strong>Services</strong> tool to finish configuring the service.</p> <ul> <li><strong>start → Settings → Control Panel → Administrative Tools → Services</strong></li> </ul> <p>At a very minimum, you should verify the configuration settings for the following items:</p> <ul> <li><strong>Description</strong> - A description of the service.</li> <li><strong>Startup Type</strong> - <em>Manual</em> or <em>Automatic</em>?</li> <li><strong>Log On</strong> - The account determines what rights the service has.</li> </ul> <p>Once you are done, you can start the service.</p> <h2>3. Advanced Configuration: The Windows Registry</h2> <p>Windows stores information about how to run services in the registry. If you want to play around with some of the service settings, and you are comfortable working directly with <strong>RegEdit.exe</strong>, you can save yourself some time and effort over recreating and reconfiguring the service each time. Note that when you change a registry setting, you will have to restart the service for it to become effective.</p> <p>The following figure shows typical registry settings for the <strong>Gosh Sample Service</strong>, included in the sample project. You may notice a number of familiar parameters, such as the classpath and the maximum heap size. These can all be edited, and it is pretty obvious what each one means.</p> <p><img class="confluence-embedded-image" src="/download/attachments/230400689/service_params.jpg?version=1&modificationDate=1368953024989" data-image-src="/download/attachments/230400689/service_params.jpg?version=1&modificationDate=1368953024989" data-linked-resource-id="230565145" data-linked-resource-type="attachment" data-linked-resource-default-alias="service_params.jpg" data-base-url="http://docs.codehaus.org" data-linked-resource-container-id="230400689" title="null > service_params.jpg"><br class="atl-forced-newline" /></p> <h1>Writing a Service</h1> <p>At this point, you are probably wondering what the difference is between a regular <strong>Groovy</strong> script and <strong>Groovy</strong> script that runs as a <strong>Windows Service</strong>. </p> <p>There is a difference. A <strong>Groovy</strong> script does a job, and when it is finished, it ends. With a <strong>Windows Service</strong>, the program doesn't end until Windows asks it to. You can implement this - very simply - by creating a loop that checks a flag to exit. <br class="atl-forced-newline" /></p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> while(!service.shutdownRequested) { doSomethingServicey() service.sleep 5000 //Wait 5 seconds. } </pre></td></tr></table> <p>That is really all there is to it. The <strong>service</strong> instance is one of the bindings. <strong>service.shutdownRequested</strong> returns <strong>true</strong> when Windows has requested that the service be shutdown. <strong>service.sleep</strong> is a variation on <strong>Thread.sleep()</strong> that returns immediately if the service has been requested to shut down.</p> <h1>Examples</h1> <p>There are several examples in the <strong>.\gosh\sample</strong> project, included in the build. </p> <p>The <strong>winntservice</strong> example implements a complete <strong>Windows Service</strong>, ready to install and run. To use:</p> <ul> <li>Run <strong>installsampleservice.bat</strong> from a command-line.</li> <li>Using the <strong>Services</strong> tool, start the service.</li> <li>Check the log files to verify that the service is running.</li> </ul> <p>There are also a few command-line examples in the same project.</p> <h1>Bindings</h1> <p><strong>Gosh</strong> automatically creates a number of bindings. All of these are available to your script as variables, both when run as a service and when run from the command-line.</p> <table class="confluenceTable"><tbody> <tr> <th class="confluenceTh"><p> Name </p></th> <th class="confluenceTh"><p> Type </p></th> <th class="confluenceTh"><p> Description </p></th> </tr> <tr> <td class="confluenceTd"><p> args </p></td> <td class="confluenceTd"><p> List </p></td> <td class="confluenceTd"><p> When run from the command-line, this contains the command-line arguments. When run as a service, this is an empty list. <strong>Gosh</strong> does not support passing parameters to a service. </p></td> </tr> <tr> <td class="confluenceTd"><p> service </p></td> <td class="confluenceTd"><p> ServiceRunner </p></td> <td class="confluenceTd"><p> Provides state information about the service. When running from a command line, the state information never changes, so you have to shut down the process manually. </p></td> </tr> <tr> <td class="confluenceTd"><p> systemClassLoader </p></td> <td class="confluenceTd"><p> GoshClassLoader </p></td> <td class="confluenceTd"><p> The <strong>Java</strong> system classloader. This classloader allows you add add <strong>JAR</strong> files and new classpaths at runtime. </p></td> </tr> <tr> <td class="confluenceTd"><p> groovyClassLoader </p></td> <td class="confluenceTd"><p> GroovyClassLoader </p></td> <td class="confluenceTd"><p> The <strong>Groovy</strong> classloader. Note that the parent of the <strong>groovyClassLoader</strong> is the <strong>systemClassLoader</strong>. </p></td> </tr> <tr> <td class="confluenceTd"><p> fs </p></td> <td class="confluenceTd"><p> FileSystem </p></td> <td class="confluenceTd"><p> Supports finding the root path of your project, creating files from the root of your project (rather than the current folder) using relative paths, and changing the <strong>java.library.path</strong>, among other things. </p></td> </tr> <tr> <td class="confluenceTd"><p> scriptFile </p></td> <td class="confluenceTd"><p> File </p></td> <td class="confluenceTd"><p> The canonical path to the initial <strong>Groovy</strong> script. </p></td> </tr> </tbody></table> <p><br class="atl-forced-newline" /></p> <h1>Classloader Architecture</h1> <p>The classloader architecture in <strong>Gosh</strong> differs somewhat from the architecture found in other the other command-line runners for <strong>Groovy</strong>. <strong>Gosh</strong> replaces the <strong>RootClassLoader</strong> with the <strong>GoshClassLoader</strong>, which is a very simple override of <strong>UrlClassLoader</strong>. </p> <p><strong>Gosh</strong> is broken into two <strong>JAR</strong> files. The first, <strong>dasboot.jar</strong>, contains the minimal number of classes to boot <strong>Gosh</strong>. This includes the <strong>main</strong> entry class, the <strong>GoshClassLoader</strong>, and a small number of supporting classes. Once <strong>dasboot.jar</strong> is loaded, the system classloader gets set to an instance of <strong>GoshClassLoader</strong>, and all the other class libraries, including <strong>gosh.jar</strong>, are added to it.</p> <p>Once that is done, <strong>Gosh</strong> creates a <strong>GroovyClassLoader</strong>, which is a child of the system classloader. This classloader is pointed to the root folder of the project, where it interprets uncompiled <strong>Groovy</strong> scripts. </p> <p>In all cases, we have attempted to use the simplest, tightest classloader structure that works. This results in optimal loading and execution times. <br class="atl-forced-newline" /></p> <h1>Limitations</h1> <p>The following are known limitations of <strong>Gosh</strong>: </p> <ul> <li>You can't typically use this to bootstrap complex application servers, like <strong>Tomcat</strong> and <strong>JBoss</strong>, due to the modified classloader structure and potential conflicts with <strong>Groovy JAR</strong> library dependencies. If anyone has success doing this, please contact me.</li> </ul>
Please type the word appearing in the picture.
Attachments
Labels
Location
Watch this page
< Edit
Preview >
Loading…
Save
Cancel
Next hint
search
attachments
weblink
advanced