(applets, anyone?) • Groovy/Grails since 2009 • Lead developer for IEEE Spectrum • Always been a closet fan of dynamic languages (starting with Perl) Wednesday, October 17, 12
Widely known for standards - 802.11 • World’s largest technology professional association - 400,000 engineers in 160 countries • Publishes nearly a third of the world’s technical literature in EE/CS Wednesday, October 17, 12
referrals from HN, Reddit, /. • 100% Groovy/Grails since 2009 - both front-end and CMS • Akamai/Weblogic/Oracle stack • Award-winning coverage of ROBOTS! Wednesday, October 17, 12
new website...” • “You must use the standard corporate Enterprise CMS system.” • “Can’t you guys just make a copy of the existing code and tweak it?” • DANGER! Wednesday, October 17, 12
Controllers/Views/ Services (e.g. article, blog pages) Domain classes (e.g Article, BlogPost) CMS Controllers/ Views/Services Quartz Jobs (e.g. sitemap generation) Spectrum Taglib Utility classes (src/**) UrlMappings Test classes Front End & CMS images, CSS, JS Where do we go from here? Wednesday, October 17, 12
system • Can implement common functionality in plugins that is overridden by application • Can create new Artifact types • Interact with Spring context • Integrated with build system Wednesday, October 17, 12
plugins repository • Search on plugin portal http://grails.org/plugins/ • Quickly bootstrap new applications • Spend some time now save some time later • Follow @grailsplugins for updates Wednesday, October 17, 12
Standard Grails artifacts: GSPs, Controllers, Services, i18n, TagLibs - just like in app • Define custom Grails artifact types: see Quartz plugin “Jobs” • Plugins can depend on other plugins Wednesday, October 17, 12
version = "0.1" // the version or versions of Grails the plugin is designed for def grailsVersion = "2.1 > *" // the other plugins this plugin depends on def dependsOn = [:] def doWithDynamicMethods = { ctx -> // TODO Implement registering dynamic methods to classes (optional) } def doWithApplicationContext = { applicationContext -> // TODO Implement post initialization spring config (optional) } Wednesday, October 17, 12
URL: grails install-plugin http://myserver.com/plugins/grails- example-0.1.zip in BuildConfig.groovy (“in-place” plugin): // Uncomment this only for local development - do not check in! grails.plugin.location.'spectrum-core' = '../spectrum-core' Wednesday, October 17, 12
domain-specific • Code reuse within an organization • Can be coarse-grained, heavyweight • Private forks of public plugins • Enable interesting options for application architecture Private Plugins Wednesday, October 17, 12
applications tend to become unmanageable over time • Convention-based directory trees (e.g. /grails-app/views ) • Rapid development/scaffolding • Need “separation of concerns” Wednesday, October 17, 12
between applications • Different applications, same DB instance • Hibernate not included in plugins by default • Consider Hibernate caching issues DB Primary web application Domain Model plugin API endpoint application Domain Model plugin Reporting application Domain Model plugin Wednesday, October 17, 12
Controllers/ Views/Services Quartz Jobs Front End Taglib Utility classes (src/**) Front End UrlMappings Test classes Front End images, CSS, JS CMS test classes CoreUrlMappings Spectrum Core Plugin Spectrum Application CMS images, CSS, JS Common Front End Controllers Core Services CMS Taglib Depends on other plugins: spring-security-core, quartz, searchable, ckeditor, and others Wednesday, October 17, 12
• View resolution: application first, then plugin • Can specify plugin using <g:render plugin=”myplugin”> • The promise of MVC fulfilled! Wednesday, October 17, 12
to fix certain config properties - won’t need them in application Config • Manually merge config in doWithSpring • application.config.merge(new ConfigSlurper().parse(application.classLoader.loadClass('MyPluginConfig '))) Wednesday, October 17, 12
- e.g. Artifactory or Nexus • Release plugin - installed by default • Old-style svn-based repos supported, but not recommended for Grails 2 • Customize plugin metadata with internal Maven groupId • Publish from Jenkins Wednesday, October 17, 12
local dev workspace (BuildConfig.groovy) • Private plugins tend to be updated along with application features • Beware of potential breaking changes (in other applications) • Define deprecation strategy and use @deprecated javadoc Wednesday, October 17, 12
new empty plugin & plugin descriptor • Move Grails artifacts (e.g. Controllers, Services, Views, etc.) into new plugin • Move dependent files from /src • Move related test files into new plugin • Remove hard coded paths to resources • Run your functional test suite Wednesday, October 17, 12
of application with shared code DB Business- facing application Core application plugin Public-facing application Core application plugin Public Internet Private intranet Wednesday, October 17, 12
data management server application Clinical data review application Data Capture plugin Data Cleaning plugin Data Validation plugin Super-plugin to combine plugin dependencies into a platform or domain-specific framework Wednesday, October 17, 12
sauce” Full application DB Shell application (external team) Split application into separate parts to isolate key algorithms from external vendor Wednesday, October 17, 12
entry to Config.groovy and then forget about it • Group together plugin config properties into a closure • Don’t forget about external config files and differences in various environments Wednesday, October 17, 12
resolution error-prone • See JIRA for bugs related to plugins • Avoid creating many small plugins • Strange problems? Look at your build. Wednesday, October 17, 12
Be prepared to branch/merge • Be sure to update plugin versions and tag your code consistently • Just use Git - merging & cherry- picking are sweet Wednesday, October 17, 12
packaged in a path corresponding to plugin name & version - /plugins/ myplugin-1.0/* • path changes between dev mode and WAR - <g:resource> handles correctly • May need to redeploy with each plugin version bump • Don’t accidentally share sensitive files! Wednesday, October 17, 12
Private plugins are a safe, robust way to modularize Grails applications • Private plugins enable coarse-grained reuse of application components • Configuration management and OO principles are important (as always) Wednesday, October 17, 12