15 プラグイン - Reference Documentation
Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith
Version: 2.3.0
Translated by: T.Yamamoto, Japanese Grails Doc Translating Team. Special thanks to NTT Software.
【注意】このドキュメントの内容はスナップショットバージョンを元に*意訳*されているため、一部現行バージョンでは未対応の機能もあります。
Table of Contents
15 プラグイン
15.1 プラグインの作成とインストール
Creating Plugins
プラグインの作成
Grailsプラグインの新規作成は、以下のコマンドを実行するだけであり、とても簡単です:
grails create-plugin [PLUGIN NAME]
grails create-plugin example
would create a new plugin project called example
.grails create-plugin example
を実行すると、example
という新規プラグインプロジェクトが作成されます。Make sure the plugin name does not contain more than one capital in a row, or it won't work. Camel case is fine, though.
The only plugins included in a new plugin project are Tomcat and Release. Hibernate is not included by default.新規プラグインプロジェクトには、TomcatプラグインとReleaseプラグインが含められています。Hibernateプラグインはデフォルトの状態では含められていません。
Grailsプラグインの構成が「通常のGrailsプロジェクト」と同じであることには利点が多くあります。例えば、以下を実行することでテストが実行できます。
grails run-app
Plugin projects don't provide an index.gsp by default since most plugins don't need it. So, if you try to view the plugin running in a browser right after creating it, you will receive a page not found error. You can easily create agrails-app/views/index.gsp
for your plugin if you'd like.プラグインプロジェクトは、index.gspをデフォルトでは提供しません。なぜならほとんどのプラグインでは必要ないからです。なので、プラグイン起動後にブラウザで確認しようとすると「ページが見つかりません」というエラーになるでしょう。もちろん、もしそうしたければプラグインプロジェクト中に
grails-app/views/index.gsp
を作成しても全く問題ありません。
GrailsPlugin
and is found in the root of the plugin project. For example:
GrailsPlugin
」であり、プラグインプロジェクトのルートディレクトリに配置されます。例えば:class ExampleGrailsPlugin { def version = "0.1"… }
このようなクラスがプラグインディレクトリのルートに存在しなければなりません。このプラグインクラスは、プラグインのバージョン情報や他のメタデータを定義しています。さらに、プラグイン拡張ポイントへの様々なフックを定義することができます(簡易にカバー)。
さらに、いくつかの特別なプロパティを使って、プラグインの追加情報を提供することもできます。
title
- short one-sentence description of your pluginversion
- The version of your plugin. Valid values include example "0.1", "0.2-SNAPSHOT", "1.1.4" etc.grailsVersion
- The version of version range of Grails that the plugin supports. eg. "1.2 > *" (indicating 1.2 or higher)author
- plugin author's nameauthorEmail
- plugin author's contact e-maildescription
- full multi-line description of plugin's featuresdocumentation
- URL of the plugin's documentation
title
- このプラグインを説明する短い一文。version
- このプラグインのバージョン。例えば「0.1」「0.2-SNAPSHOT」「1.1.4」などの有効な値。grailsVersion
- プラグインがサポートするGrailsのバージョンを、バージョン範囲で指定する。例えば「1.2 > *」(これは「1.2以上」であることを示す)author
- プラグインの開発者名authorEmail
- プラグイン開発者に連絡するためのe-mailアドレスdescription
- 複数行に渡るプラグイン機能のフル説明documentation
- プラグインのドキュメントへのURL
class QuartzGrailsPlugin { def version = "0.1" def grailsVersion = "1.1 > *" def author = "Sergey Nebolsin" def authorEmail = "nebolsin@gmail.com" def title = "Quartz Plugin" def description = '''\ The Quartz plugin allows your Grails application to schedule jobs\ to be executed using a specified interval or cron expression. The\ underlying system uses the Quartz Enterprise Job Scheduler configured\ via Spring, but is made simpler by the coding by convention paradigm.\ ''' def documentation = "http://grails.org/plugin/quartz"… }
Installing Local Plugins
To make your plugin available for use in a Grails application run the maven-install
command:
grails maven-install
This will install the plugin into your local Maven cache. Then to use the plugin within an application declare a dependency on the plugin in your grails-app/conf/BuildConfig.groovy
file:
compile
Notes on excluded Artefacts
アーテファクト除外についての留意事項
前述のように、create-pluginコマンドはプラグインプロジェクトとして一連のファイルを作成し、Grailsアプリケーションとして実行することもできますが、パッケージ化したときにこれら全てのファイルが含められるわけではありません。以下は、生成されるけれども、package-pluginコマンドで生成されるzipファイルには含まれないアーテファクトのリストです。
grails-app/conf/BootStrap.groovy
grails-app/conf/BuildConfig.groovy
(although it is used to generatedependencies.groovy
)grails-app/conf/Config.groovy
grails-app/conf/DataSource.groovy
(and any other*DataSource.groovy
)grails-app/conf/UrlMappings.groovy
grails-app/conf/spring/resources.groovy
- Everything within
/web-app/WEB-INF
- Everything within
/web-app/plugins/**
- Everything within
/test/**
- SCM management files within
**/.svn/**
and**/CVS/**
grails-app/conf/BootStrap.groovy
grails-app/conf/BuildConfig.groovy
(dependencies.groovy
の生成には使用される)grails-app/conf/Config.groovy
grails-app/conf/DataSource.groovy
(これと他の任意の*DataSource.groovy
)grails-app/conf/UrlMappings.groovy
grails-app/conf/spring/resources.groovy
/web-app/WEB-INF
配下のすべて/web-app/plugins/**
配下のすべて/test/**
配下のすべて**/.svn/**
と**/CVS/**
配下のSCM管理ファイル
WEB-INF
it is recommended you use the _Install.groovy
script (covered later), which is executed when a plugin is installed, to provide such artefacts. In addition, although UrlMappings.groovy
is excluded you are allowed to include a UrlMappings
definition with a different name, such as MyPluginUrlMappings.groovy
.
アーテファクトをWEB-INF
に含める必要がある場合には、プラグインインストール時に実行されるスクリプトである_Install.groovy
スクリプト(後述)を使用することがお勧めです。なお、除外対象アーティファクトであるUrlMappings.groovy
は除外されますが、UrlMappings
情報は「MyPluginUrlMappings.groovy
」などの異なる名前にしておけば、含めることができます。
Customizing the plugin contents
You can specify what to exclude in addition to the default excludes by adding elements to the pluginExcludes
descriptor property (described below). In addition, there are two ways to configure the contents of the plugin ZIP or JAR file.
One is to create an event handler for the CreatePluginArchiveStart
event, which is fired after all of the plugin files have been copied to the staging directory. By adding an event handler you can add, modify, or delete files as needed. Add the handler to _Events.groovy
in the scripts
directory, for example
eventCreatePluginArchiveStart = { stagingDir -> // update staging directory contents here }
You can customize the location of the staging directory with the grails.project.plugin.staging.dir
attribute in BuildConfig.groovy
or as as system property.
Note that there is also a CreatePluginArchiveEnd
event which is fired after the ZIP or JAR is packaged.
You can also do this work in a Closure in BuildConfig.groovy
with the property grails.plugin.resources
which is analogous to the grails.war.resources
property, e.g.
grails.plugin.resources = { stagingDir -> // update staging directory contents here }
Specifying Plugin Locations
プラグイン位置の指定
grails-app/conf/BuildConfig.groovy
file:
アプリケーションは、ファイルシステム上の任意の場所にあるプラグインをロードできますし、インストールしていないプラグインをロードすることさえも可能です。そのためには、アプリケーションのgrails-app/conf/BuildConfig.groovy
設定ファイルに、パッケージされていないプラグインのディレクトリを以下のように指定します:
// Useful to test plugins you are developing. grails.plugin.location.shiro = "/home/dilbert/dev/plugins/grails-shiro"// Useful for modular applications where all plugins and // applications are in the same directory. grails.plugin.location.'grails-ui' = "../grails-grails-ui"
// 開発中のプラグインをテストするのに便利。 grails.plugin.location.shiro = "/home/dilbert/dev/plugins/grails-shiro"// すべてのプラグインとアプリケーションを同じディレクトリに置き、 // モジュール化するのに便利。 grails.plugin.location.'grails-ui' = "../grails-grails-ui"
- You are developing a plugin and want to test it in a real application without packaging and installing it first.
- You have split an application into a set of plugins and an application, all in the same "super-project" directory.
これが特に便利なのは、以下の2つの場合です:
- 開発中のプラグインを、パッケージ化とインストールをスキップして、実アプリケーションにすぐに組み込んでテストしたいとき。
- アプリケーションが複数のプラグイン群に分割されており、それらすべてが同じ「スーパープロジェクト」ディレクトリ配下にある場合。
The Artifactory repository for Grails now includes all the dependencies for published plugins. So, if you are using inline plugins that have dependencies, it is necessary to do a secondary resolve because these dependencies might not be in the repository. Therefore, you should setlegacyResolve
totrue
in yourBuildConfig.groovy
if you are using inline plugins with dependencies.
15.2 プラグインリポジトリ
プラグインをGrailsセントラルリポジトリに公開する
grails list-plugins
このコマンドはセントラルリポジトリのすべてのプラグインを一覧表示します。あなたのプラグインをplugin-infoコマンドで表示することもできます:
grails plugin-info [plugin-name]
これで説明や著者名、その他のプラグイン情報などを表示させることができます。
If you have created a Grails plugin and want it to be hosted in the central repository, you'll find instructions for getting an account on this wiki page.
もしGrailsプラグインを開発して、セントラルリポジトリでホスティングしたい場合、アカウント入手の手順はこのWikiページにあります。
grails-app/conf/BuildConfig.groovy
file:Grailsプラグインリポジトリにアクセス権を持っていれば、リリースプラグインを grails-app/conf/BuildConfig.groovy
ファイルの依存管理'build'スコープに定義してインストールします。
grails.project.dependency.resolution = { … plugins { build ':release:3.0.0' } }
And execute the publish-plugin
command to release your plugin:
grails publish-plugin
This will automatically publish the plugin to the central repository. If the command is successful, it will immediately be available on the plugin portal at http://grails.org/plugin/<pluginName>. You can find out more about the Release plugin and its other features in its user guide.
追加リポジトリの設定
Grailsにおけるリポジトリの設定手順は、Grailsのバージョンによって異なっています。Grails 1.2以前の情報についてはGrails 1.2のドキュメンテーションを参照ください。以降の節は、Grails 1.3以降について記述しています。
grails-app/conf/BuildConfig.groovy
:Grails 1.3以上では、下位層に隠されているIvyがプラグインの依存性を解決します。プラグインリポジトリを追加定義する仕組みは、 JAR依存性を定義する方法とほぼ同じです。例えば、Grailsプラグインを含むリモートMavenリポジトリを定義するには、 grails-app/conf/BuildConfig.groovy
中で以下のように記述します:
repositories { mavenRepo "http://repository.codehaus.org"// ...or with a name mavenRepo name: "myRepo", root: "http://myserver:8081/artifactory/plugins-snapshots-local" }
grailsRepo
method:grailsRepo
メソッドを使ってSVNベースのGrailsリポジトリ(例えばhttp://plugins.grails.orgでホストされているリポジトリ)を定義することもできます:
repositories { grailsRepo "http://myserver/mygrailsrepo"// ...or with a name grailsRepo "http://myserver/svn/grails-plugins", "mySvnRepo" }
repositories { grailsCentral() }
repositoriesの項目で列挙した順にプラグインは解決されます。なので以下ではGrailsセントラルリポジトリが最後に検索されます:
repositories {
grailsRepo "http://myserver/mygrailsrepo"
grailsCentral()
}
前述の例ではHTTPを使用していましたが、プラグイン解決に任意のIvyリゾルバを使用することもできます。以下はSSHリゾルバを使用する例です:
def sshResolver = new SshResolver(user:"myuser", host:"myhost.com") sshResolver.addArtifactPattern( "/path/to/repo/grails-[artifact]/tags/" + "LATEST_RELEASE/grails-[artifact]-[revision].[ext]") sshResolver.latestStrategy = new org.apache.ivy.plugins.latest.LatestTimeStrategy()sshResolver.changingPattern = ".*SNAPSHOT" sshResolver.setCheckmodified(true)
上記の例では、プラグインZIPファイルを解決する方法をIvyに伝えるため、アーテファクトのパターンを指定しています。Ivyパターンのより詳しい説明は、Ivyユーザガイドの関連するセクションを参照下さい。
Maven互換リポジトリへの公開
In general it is recommended for Grails 1.3 and above to use standard Maven-style repositories to self host plugins. The benefits of doing so include the ability for existing tooling and repository managers to interpret the structure of a Maven repository.
You use the Release plugin to publish a plugin to a Maven repository. Please refer to the section of the Maven deployment user guide on the subject.
15.3 プラグイン構造を理解する
すでに述べてきているように、プラグインは基本的にはプラグインディスクリプタが付随した通常のGrailsアプリケーションです。しかしながら、インストールされるときにはプラグインの構造は少し異なってきます。例えば、以下のプラグイン構造を見てみましょう:
+ grails-app + controllers + domain + taglib etc. + lib + src + java + groovy + web-app + js + css
grails-app
directory will go into a directory such as plugins/example-1.0/grails-app
. They will not be copied into the main source tree. A plugin never interferes with a project's primary source tree.プラグインがインストールされたときには、grails-app
ディレクトリの内容はplugins/example-1.0/grails-app
に入ります。これらはメインアプリのソースツリーにはインストールされません。プラグインはプロジェクト本体側のソースツリーには決して干渉しないのです。
web-app
directory. You can then link to static resources just like in an application. This example links to a JavaScript source:静的リソースの処理は、少しだけ異なってきます。プラグインをあたかもアプケーションのように開発する際、すべての静的リソースはweb-app
ディレクトリに入ります。静的リソースをアプリケーションからリンクすることもできます。以下の例ではJavaScriptソースをリンクしています:
<g:resource dir="js" file="mycode.js" />
/js/mycode.js
. However, when the plugin is installed into an application the path will automatically change to something like /plugin/example-0.1/js/mycode.js
and Grails will deal with making sure the resources are in the right place.プラグインを開発モード(development mode)で実行するときは、このようなリソースへのリンクは/js/mycode.js
などに解決されます。しかし、プラグインがアプリケーションにインストールされたときは、パスは自動的に/plugin/example-0.1/js/mycode.js
のように自動的に変換され、Grailsはリソースを正しく扱うことができます。
pluginContextPath
variable that can be used whilst both developing the plugin and when in the plugin is installed into the application to find out what the correct path to the plugin is.プラグイン開発モードと、プラグインがアプリケーションにインストールされている場合のいずれにおいても、plugin.jsの正しいパスを見付けるのに、そのためのpluginContextPath
変数を使用できます。
pluginContextPath
variable will either evaluate to an empty string or /plugins/example
depending on whether the plugin is running standalone or has been installed in an applicationスタンドアローン実行中かアプリケーションにインストールされているかによって、pluginContextPath
変数は空文字列もしくは/plugins/example
のいずれかに実行時に評価されます。
src/java
and src/groovy
directories will be compiled into the main project's web-app/WEB-INF/classes
directory so that they are made available at runtime.プラグインが提供する、libやsrc/java
やsrc/groovy
ディレクトリ配下にあるJavaやGroovyコードは、実行時に利用できるようにメインプロジェクトのweb-app/WEB-INF/classes
ディレクトリ配下にコンパイルされます。
15.4 基本アーティファクトの提供
新たにスクリプトを追加する
プラグインのscriptディレクトリ配下に関連するGantスクリプトを置くことで、プラグインは新しいスクリプトを追加することができます:
+ MyPlugin.groovy + scripts <-- additional scripts here + grails-app + controllers + services + etc. + lib
+ MyPlugin.groovy + scripts <-- ここにスクリプトを追加する + grails-app + controllers + services + etc. + lib
Grails-appアーテファクト(Controller, Tag Library, Service, 他)の追加
grails-app
tree. Note that the plugin is loaded from where it is installed and not copied into the main application tree.grails-app
配下のツリーに関連するファイルを置いておくことで、プラグインは新しいアーテファクトを追加することができます。プラグインはインストールされた場所から読み込まれるのであって、メインアプリのツリー中にコピーされるわけではないことに留意して下さい。
+ ExamplePlugin.groovy + scripts + grails-app + controllers <-- コントローラを追加するのはここ。 + services <-- サービスを追加するのはここ。 + etc. <-- 他も同様。 + lib
ビューとテンプレートの提供、そしてビューの解決
grails-app/views
directory.プラグインがコントローラを提供するときは、レンダリングされるデフォルトのビューを提供しても構いません。これはアプリケーションをプラグインに分割するのに優れた方法です。
Grailsのビュー解決機構は、最初にプラグインがインストールされた親アプリケーション中のビューを探し、見付からなければプラグイン自身のビューを探してみます。これが意味するのは、アプリケーションのgrails-app/views
ディレクトリ中に対応するGSPを定義しておくことで、プラグインが提供するビューを上書きすることができるということです。
BookController
that's provided by an 'amazon' plugin. If the action being executed is list
, Grails will first look for a view called grails-app/views/book/list.gsp
then if that fails it will look for the same view relative to the plugin.例えば、「アマゾン」プラグインが提供するBookController
を考えてみて下さい。もしlist
アクションが実行されたなら、Grailsは最初にgrails-app/views/book/list.gsp
を検索し、それに失敗した場合にプラグインディレクトリから相対的に同じ位置にあるビューを検索します。
しかしながら、同じくプラグインが提供するテンプレートをビューが使用しているときには、以下の構文が必要になります:
<g:render template="fooTemplate" plugin="amazon"/>
plugin
attribute, which contains the name of the plugin where the template resides. If this is not specified then Grails will look for the template relative to the application.plugin
属性でテンプレートがあるプラグインの名前を指定することに注意下さい。もしこれがなければ、Grailsはアプリケーション相対でテンプレートを探します。
アーテファクトを除外する
デフォルトでは、Grailsはプラグインのパッケージングの過程で以下のファイルを除外します:
grails-app/conf/BootStrap.groovy
grails-app/conf/BuildConfig.groovy
(although it is used to generatedependencies.groovy
)grails-app/conf/Config.groovy
grails-app/conf/DataSource.groovy
(and any other*DataSource.groovy
)grails-app/conf/UrlMappings.groovy
grails-app/conf/spring/resources.groovy
- Everything within
/web-app/WEB-INF
- Everything within
/web-app/plugins/**
- Everything within
/test/**
- SCM management files within
**/.svn/**
and**/CVS/**
grails-app/conf/BootStrap.groovy
grails-app/conf/BuildConfig.groovy
(この情報はdependencies.groovy
の生成に用いられるが、BuildConfig自体は含められない)grails-app/conf/Config.groovy
grails-app/conf/DataSource.groovy
(その他の*DataSource.groovy
も同様)grails-app/conf/UrlMappings.groovy
grails-app/conf/spring/resources.groovy
/web-app/WEB-INF
中のすべて/web-app/plugins/**
中のすべて/test/**
中のすべて**/.svn/**
と**/CVS/**
中のSCMが管理するファイル
web-app/WEB-INF
directory it is recommended that you modify the plugin's scripts/_Install.groovy
Gant script to install these artefacts into the target project's directory tree.もしプラグインがweb-app/WEB-INF
ディレクトリ配下のファイルを必要とするなら、プラグインディレクトリのscripts/_Install.groovy
Gantスクリプトを修正し、それらのアーテファクトをターゲットのプロジェクトのディレクトリツリーにコピーするようにすることをお勧めします。
UrlMappings.groovy
file is excluded to avoid naming conflicts, however you are free to add a UrlMappings definition under a different name which will be included. For example a file called grails-app/conf/BlogUrlMappings.groovy
is fine.加えて、名前衝突を避けるため、デフォルトではUrlMappings.groovy
ファイルは除外されていますが、「UrlMapping」が含まれる異なる名前のUrlMappings定義を追加するのは構いません。例えば、grails-app/conf/BlogUrlMappings.groovy
などの名前にしておくと良いでしょう。
pluginExcludes
property:除外リストはpluginExcludes
プロパティで拡張することができます:
// resources that are excluded from plugin packaging
def pluginExcludes = [
"grails-app/views/error.gsp"
]
// プラグインのパッケージングからは除外するリソース
def pluginExcludes = [
"grails-app/views/error.gsp"
]
この指定は、デモやテスト用リソースとしてプラグインのソースリポジトリには含めたいが、プラグインとしての最終配布物には含めたくない、という場合に有用でしょう。
15.5 規約の評価
application
variable which is an instance of the GrailsApplication interface.Grailsが提供する、規約ベースのランタイム設定を見ていく前に、あなたが理解しておくべきことは、これらのプラグインの規約がどう評価されるか、ということです。どのプラグインも、暗黙のapplication
変数を持っていて、これはGrailsApplicationのインスタンスです。
GrailsApplication
interface provides methods to evaluate the conventions within the project and internally stores references to all artifact classes within your application.このGrailsApplication
インターフェースは、プロジェクト中の規約を評価するためのメソッドを提供します。また、内部的にあなたのアプリのすべてのアーテファクトクラスへの参照を保存します。
GrailsClass
instances you can do:アーテファクトはGrailsClassインターフェースを実装し、コントローラやタグライブラリのようなGrailsのリソースを表現します。例えばすべてのGrailsClass
インスタンスを取得するには以下のようにします:
for (grailsClass in application.allClasses) {
println grailsClass.name
}
GrailsApplication
has a few "magic" properties to narrow the type of artefact you are interested in. For example to access controllers you can use:GrailsApplication
はいくつかの「マジック」プロパティを持っていて、あなたの興味があるアーテファクトの型を狭めることができます。例えば、コントローラにアクセスするには以下のようにできます:
for (controllerClass in application.controllerClasses) {
println controllerClass.name
}
*Classes
- Retrieves all the classes for a particular artefact name. For exampleapplication.controllerClasses
.get*Class
- Retrieves a named class for a particular artefact. For exampleapplication.getControllerClass("PersonController")
is*Class
- Returnstrue
if the given class is of the given artefact type. For exampleapplication.isControllerClass(PersonController)
*Classes
- 特定のアーテファクト名のすべてのクラスを取り出す。 例えばapplication.controllerClasses
。get*Class
- 特定のアーテファクトの、指定した名前のクラスを取り出す。 例えばapplication.getControllerClass("PersonController")
。is*Class
- もし指定したクラスが指定したアーテファクトタイプであればtrue
を返す。 例えば、application.isControllerClass(PersonController)
。
GrailsClass
interface has a number of useful methods that let you further evaluate and work with the conventions. These include:GrailsClass
インターフェースは、規約に関する評価や処理をさらに容易にするための、以下のような便利なメソッド群を持っています:
getPropertyValue
- Gets the initial value of the given property on the classhasProperty
- Returnstrue
if the class has the specified propertynewInstance
- Creates a new instance of this class.getName
- Returns the logical name of the class in the application without the trailing convention part if applicablegetShortName
- Returns the short name of the class without package prefixgetFullName
- Returns the full name of the class in the application with the trailing convention part and with the package namegetPropertyName
- Returns the name of the class as a property namegetLogicalPropertyName
- Returns the logical property name of the class in the application without the trailing convention part if applicablegetNaturalName
- Returns the name of the property in natural terms (eg. 'lastName' becomes 'Last Name')getPackageName
- Returns the package name
getPropertyValue
- そのクラスの指定したプロパティの初期値を取得する。hasProperty
- もしクラスが指定したプロパティを持っていたらtrue
を返す。newInstance
- このクラスの新しいインスタンスを返す。getName
- 取得可能であれば、末尾の規約部分を除いた、アプリケーションにおける論理名を返す。getShortName
- そのクラスのパッケージ接頭辞を除いた短縮名を返す。getFullName
- 末尾の規約部分と先頭のパッケージ部分を含むクラスのフルネームを返す。getPropertyName
- クラス名をプロパティ名として返す。getLogicalPropertyName
- 末尾の規約部分を除き、アプリケーションにおけるクラスの論理プロパティ名を返す。getNaturalName
- 自然な語句としてのプロパティ名を返す。(例: 'lastName'は'Last Name'になる)getPackageName
- パッケージ名を返す。
全体のリファレンスについては、javadoc APIを参照してください。
15.6 ビルドイベントのフック
Post-Install設定とアップグレード
scripts
directory of the plugin - _Install.groovy
and _Upgrade.groovy
.Grailsプラグインはpost-install設定を行なったり、アプリケーションの更新プロセス(upgradeコマンドで実行する)に介在することができます。これは2つの特別な名前のスクリプト、_Install.groovy
と_Upgrade.groovy
スクリプトを、プラグインのscripts
ディレクトリ配下に置くことで可能になります。
_Install.groovy
is executed after the plugin has been installed and _Upgrade.groovy
is executed each time the user upgrades the application (but not the plugin) with upgrade command._Install.groovy
はプラグインがインストールされた後に実行され、_Upgrade.groovy
コマンドはアプリケーションが upgradeコマンドで更新されるたびに実行されます(プラグインをupgradeコマンドで更新した時ではありません)。
pluginBasedir
variable which points at the plugin installation basedir.これらのスクリプトは、Gantスクリプトであり、Gantの全機能を使用することができます。標準Gant変数に加えて、pluginBasedir
変数があり、プラグインがインストールされているベースディレクトリを指定しています。
_Install.groovy
script will create a new directory type under the grails-app
directory and install a configuration template:例えば、以下の_Install.groovy
スクリプトはgrails-app
ディレクトリ配下に新しいディレクトリを作成し、設定テンプレートをインストールします:
ant.mkdir(dir: "${basedir}/grails-app/jobs")ant.copy(file: "${pluginBasedir}/src/samples/SamplePluginConfig.groovy", todir: "${basedir}/grails-app/conf")
pluginBasedir
variable is not available in custom scripts, but you can use fooPluginDir
, where foo
is the name of your plugin.pluginBasedir
変数はカスタムスクリプト中では利用できませんが、foo
がプラグイン名であるとき、fooPluginDir
を使うことができます。
イベントをスクリプトで処理する
コマンドラインスクリプトを実行中のイベントをフックすることもできます。Grailsターゲットとプラグインスクリプトの実行中に発生するイベントがあります。
例えば、状態の変更イベント(「テストがパスしたとき」や「サーバが実行開始」など)や、ファイルやアーテファクトの生成イベントなどにもフックすることができます。
_Events.groovy
script to listen to the required events. Refer the documentation on Hooking into Events for further information.プラグインが必要なイベントをlistenするために必要なのは、_Events.groovy
スクリプトを提供することだけです。より詳しい情報については、イベントをフックするを参照してください。
15.7 ランタイム設定へのフック
Grailsはシステムの異なる部分を利用するために、多くのフックを提供し、規約によって実行時設定を行います。
GrailsのSpring設定にフックする
doWithSpring
which is assigned a block of code. For example the following snippet is from one of the core Grails plugins that provides i18n support:まず、doWithSpring
という名前の、クロージャブロックが代入されたプロパティを提供することで、Grails実行時設定にフックすることができます。例えば以下のコード断片は、 i18nサポートを提供するコアGrailsプラグインに含まれているものです:
import org.springframework.web.servlet.i18n.CookieLocaleResolver import org.springframework.web.servlet.i18n.LocaleChangeInterceptor import org.springframework.context.support.ReloadableResourceBundleMessageSourceclass I18nGrailsPlugin {
def version = "0.1"
def doWithSpring = { messageSource(ReloadableResourceBundleMessageSource) { basename = "WEB-INF/grails-app/i18n/messages" } localeChangeInterceptor(LocaleChangeInterceptor) { paramName = "lang" } localeResolver(CookieLocaleResolver) } }
messageSource
bean and a couple of other beans to manage Locale resolution and switching. It using the Spring Bean Builder syntax to do so.このプラグインは、GrailsのmessageSource
ビーンと、Locale解決と切り替えを行う他のいくつかのビーンを設定します。これはSpringビーンビルダのシンタックスを使用します。
web.xml生成への参加
WEB-INF/web.xml
file at load time, and although plugins cannot change this file directly, they can participate in the generation of the file. A plugin can provide a doWithWebDescriptor
property that is assigned a block of code that gets passed the web.xml
as an XmlSlurper
GPathResult
.GrailsはWEB-INF/web.xml
ファイルをロード時に生成し、プラグインはこのファイルを直接変更することはできませんが、このファイルの生成過程に参加することができます。プラグインはクロージャコードブロックが代入されたdoWithWebDescriptor
プロパティを提供することができ、そのコードにはXmlSlurper
のGPathResult
としてweb.xml
が渡されます。
servlet
and servlet-mapping
servlet
とservlet-mapping
の追加
ControllersPlugin
:ControllersPlugin
にある、以下の例を考えてみてください:
def doWithWebDescriptor = { webXml ->def mappingElement = webXml.'servlet-mapping'
def lastMapping = mappingElement[mappingElement.size() - 1] lastMapping + { 'servlet-mapping' { 'servlet-name'("grails") 'url-pattern'("*.dispatch") } } }
<servlet-mapping>
element and appends Grails' servlet after it using XmlSlurper's ability to programmatically modify XML using closures and blocks.XmlSlurperの「クロージャとブロックを使ってプログラム的にXMLを修正できる」という機能を使って、ここではプラグインは<servlet-mapping>
への参照を取得し、Grailsのサーブレットを追加しています。
filter
and filter-mapping
filter
とfilter-mapping
の追加
<filter>
element doesn't matter since order is not important, so it's simplest to insert your custom filter definition immediately after the last <context-param>
element. Order is important for mappings, but the usual approach is to add it immediately after the last <filter>
element like so:マッピングを伴うフィルターの追加は少し異なります。順序は重要ではないので、<filter>
要素の場所は問題になりません。なのでカスタムフィルタ定義を最後の<context-param>
要素のすぐ後に挿入するのが最も簡単です。マッピングに関しては 順序は重要 です。しかし通常の場合、<filter>
要素の直後に追加してしまいます:
def doWithWebDescriptor = { webXml ->def contextParam = webXml.'context-param'
contextParam[contextParam.size() - 1] + { 'filter' { 'filter-name'('springSecurityFilterChain') 'filter-class'(DelegatingFilterProxy.name) } }
def filter = webXml.'filter' filter[filter.size() - 1] + { 'filter-mapping'{ 'filter-name'('springSecurityFilterChain') 'url-pattern'('/*') } } }
フィルターは、例えばSpringの文字エンコーディングフィルタやSiteMeshフィルタなどの標準Grailsフィルターの後に実行されなければならない場合があります。この場合、以下のようにすることで、フィルタマッピングを標準のフィルタ(正確に言えば、テンプレートのweb.xmlファイルに含まれている任意のもの)のすぐ後に挿入することができます:
def doWithWebDescriptor = { webXml -> ...// Insert the Spring Security filter after the Spring // character encoding filter. def filter = webXml.'filter-mapping'.find { it.'filter-name'.text() == "charEncodingFilter" }
filter + { 'filter-mapping'{ 'filter-name'('springSecurityFilterChain') 'url-pattern'('/*') } } }
初期化設定後の実行
doWithApplicationContext
closure property.ApplicationContextが構築された後で実行時設定を行うことが有用な場合があります。そのためにはdoWithApplicationContext
クロージャプロパティを定義します。
class SimplePlugin {def name = "simple" def version = "1.1"
def doWithApplicationContext = { appCtx -> def sessionFactory = appCtx.sessionFactory // do something here with session factory } }
15.8 実行時のダイナミックメソッド追加
基本的な考え方
doWithDynamicMethods
closure.Grailsプラグインでは、Grails管理下および他のクラスに対して、実行時にダイナミックメソッドを登録することができます。これはdoWithDynamicMethods
クロージャで行ないます。
コントローラやタグライブラリなどのようなGrails管理下のクラスについては、それぞれのコントローラのMetaClassを ExpandoMetaClass の機構でアクセスすることによって、メソッドやコンストラクタなどを追加できます:
class ExamplePlugin { def doWithDynamicMethods = { applicationContext -> for (controllerClass in application.controllerClasses) { controllerClass.metaClass.myNewMethod = {-> println "hello world" } } } }
myNewMethod
to each controller. If you know beforehand the class you wish the add a method to you can simply reference its metaClass
property.この場合、暗黙のapplicationオブジェクトを使い、すべてのコントローラクラスのMetaClassの参照を取得し、それぞれのコントローラにmyNewMethod
という新規メソッドを追加しています。メソッドを追加したいクラスが予め判っていれば、そのmetaClass
プロパティを単純に参照できます。
swapCase
to java.lang.String
:例えば、swapCase
メソッドをjava.lang.String
クラスに追加できます:
class ExamplePlugin {def doWithDynamicMethods = { applicationContext -> String.metaClass.swapCase = {-> def sb = new StringBuilder() delegate.each { sb << (Character.isUpperCase(it as char) ? Character.toLowerCase(it as char) : Character.toUpperCase(it as char)) } sb.toString() }
assert "UpAndDown" == "uPaNDdOWN".swapCase() } }
アプリケーションコンテキストとの相互作用
doWithDynamicMethods
closure gets passed the Spring ApplicationContext
instance. This is useful as it lets you interact with objects within it. For example if you were implementing a method to interact with Hibernate you could use the SessionFactory
instance in combination with a HibernateTemplate
:doWithDynamicMethods
クロージャにはSpringのApplicationContext
インスタンスが渡されます。これはその中のオブジェクトとやりとりできるので便利です。例えば、Hibernateと相互作用するメソッドを定義しているなら、SessionFactory
インスタンスとHibernateTemplate
を組合せて使うことができます:
import org.springframework.orm.hibernate3.HibernateTemplateclass ExampleHibernatePlugin {
def doWithDynamicMethods = { applicationContext ->
for (domainClass in application.domainClasses) {
domainClass.metaClass.static.load = { Long id-> def sf = applicationContext.sessionFactory def template = new HibernateTemplate(sf) template.load(delegate, id) } } } }
Springコンテナにはオートワイアリング(autowiring)と依存性注入(DI)機能があるので、依存性を実行時に解決するのにアプリケーションコンテキストを使用する、より強力なダイナミックコンストラクタをあなたのオブジェクトに実装することもできます:
class MyConstructorPlugin {def doWithDynamicMethods = { applicationContext -> for (domainClass in application.domainClasses) { domainClass.metaClass.constructor = {-> return applicationContext.getBean(domainClass.name) } } } }
ここでは、デフォルトコンストラクタを、prototypeのSpringビーンをルックアップするようなコンストラクタに実際に置き換えています。
15.9 自動リロードイベントへの参加
リソース変更の監視
ServicesPlugin
:リソース変更を監視し、変更された場合に何らかのアクションを実行することが便利なときがあります。この方法を用いて、Grailsではアプリケーションの状態が実行時に変化したときに高度なリローディングを行っています。例えば、ServicesPlugin
のにあるものを単純化した以下のコード断片を見てください:
class ServicesGrailsPlugin { … def watchedResources = "file:./grails-app/services/*Service.groovy"… def onChange = { event -> if (event.source) { def serviceClass = application.addServiceClass(event.source) def serviceName = "${serviceClass.propertyName}" def beans = beans { "$serviceName"(serviceClass.getClazz()) { bean -> bean.autowire = true } } if (event.ctx) { event.ctx.registerBeanDefinition( serviceName, beans.getBeanDefinition(serviceName)) } } } }
watchedResources
as either a String or a List of strings that contain either the references or patterns of the resources to watch. If the watched resources specify a Groovy file, when it is changed it will automatically be reloaded and passed into the onChange
closure in the event
object.最初にwatchedResources
変数を定義していますが、これは監視対象としたいリソースへの参照もしくはパターンを含む、文字列もしくは文字列のリストです。もし監視されるリソースがGroovyファイルを指定しているのであれば、それが変更されたときには自動的にリロードが実行されます。そして、onChange
クロージャが呼び出され、Groovyファイルはその引数であるevent
オブジェクト中に設定されます:
event
object defines a number of useful properties:event
オブジェクトは多数の有用なプロパティを含んでいます:
event.source
- The source of the event, either the reloadedClass
or a SpringResource
event.ctx
- The SpringApplicationContext
instanceevent.plugin
- The plugin object that manages the resource (usuallythis
)event.application
- TheGrailsApplication
instanceevent.manager
- TheGrailsPluginManager
instance
event.source
- イベントの発生元。リロードされたClass
もしくはSpringResource
。event.ctx
- SpringApplicationContext
インスタンスevent.plugin
- このリソースを管理しているプラグインオブジェクト(通常this
)。event.application
-GrailsApplication
インスタンスevent.manager
-GrailsPluginManager
インスタンス
ApplicationContext
when one of the service classes changes.何が変更されたかによって異なる適切な変更をするためには、これらのオブジェクトが利用可能です。前述のサービスの例においては、サービスクラスが変更されたとき、新しいサービスビーンがApplicationContext
において再登録されます。
他のプラグインに影響を及ぼす
変更に対してリアクションするのに加え、プラグインは他のプラグインに「影響を及ぼす」必要があるときがあります。
サービスとコントローラのプラグインを例にとりましょう。サービスがリロードされた場合、コントローラもリロードしなければ、リロードされたサービスを古いコントローラクラスにオートワイヤ(auto-wire)するときに問題が発生するでしょう。
ServicesGrailsPlugin
:この問題を回避するために、どのプラグインが他のプラグインに「影響を及ぼす」のかを指定することができます。これが意味するのは、あるプラグインが変更を検出したとき、そのプラグイン自身がリロードされた後に、それが「影響を及ぼしている」プラグインもリロードされるということです。例えば、ServicesGrailsPlugin
にある以下のコード断片を考えてみましょう:
def influences = ['controllers']
他のプラグインを観察する
変更を観察したい特定のプラグインがあり、そのプラグインが監視するリソースを監視する必要がないなら、「observe」プロパティを使うことができます:
def observe = ["controllers"]
この場合、コントローラが変更されたとき、あなたのプラグインもコントローラプラグインから連鎖したイベントを受け取ります。
ワイルドカードを使えば、すべてのプラグインの変更を監視することも可能です:
def observe = ["*"]
log
property back to any artefact that changes while the application is running.ロギングプラグインはちょうどこのようなことを行なっており、アプリの実行中に変更があった 任意の アーティファクトにlog
プロパティを設定し直しています。
15.10 プラグインのロード順を理解する
プラグインの依存性制御
dependsOn
. For example, take a look at this snippet from the Hibernate plugin:プラグインはしばしば他のプラグインの存在に依存しますが、他のプラグインの存在についての依存性に適応することができます。これは2つのプロパティで行うことができます。1つ目はdependsOn
というプロパティですが、Hibernateプラグインにある以下のコード断片を見て下さい:
class HibernateGrailsPlugin {def version = "1.0"
def dependsOn = [dataSource: "1.0", domainClass: "1.0", i18n: "1.0", core: "1.0"] }
dataSource
, domainClass
, i18n
and core
plugins.Hibernateプラグインは4つのプラグインに依存しています: dataSource
、domainClass
、i18n
そしてcore
プラグインです。
依存しているプラグインは、Hibernateプラグインの前に読み込まれます。すべての依存プラグインがロードされなければ、プラグインはロードされません。
dependsOn
property also supports a mini expression language for specifying version ranges. A few examples of the syntax can be seen below:dependsOn
プロパティはバージョン範囲を指定するためのミニ式言語をサポートしています。以下は例です:
def dependsOn = [foo: "* > 1.0"] def dependsOn = [foo: "1.0 > 1.1"] def dependsOn = [foo: "1.0 > *"]
ワイルドカード文字が任意のバージョンを表わすために使われます。また、この式のシンタックスは、「-BETA」や「-ALPHA」といった接尾辞を除外します。なので例えば「1.0 > 1.1」は以下のバージョンにマッチします。
- 1.1
- 1.0
- 1.0.1
- 1.0.3-SNAPSHOT
- 1.1-BETA2
ロード順序の制御
dependsOn
establishes a "hard" dependency in that if the dependency is not resolved, the plugin will give up and won't load. It is possible though to have a weaker dependency using the loadAfter
and loadBefore
properties:dependsOn
は、依存性が解決されなければプラグインのロードをあきらめるような「ハード依存性」を確立します。loadAfter
とloadBefore
プロパティを使うことで「より弱い依存性」を使うこともできます。
def loadAfter = ['controllers']
controllers
plugin if it exists, otherwise it will just be loaded. The plugin can then adapt to the presence of the other plugin, for example the Hibernate plugin has this code in its doWithSpring
closure:ここでは、もしcontrollers
プラグインが存在すれば、それがロードされた後に、このプラグインがロードされます。 さもなければ(controllers
プラグインが存在しなければ)、このプラグインは単にロードされます。プラグインは他のプラグインの存在に適応します。たとえば、HibernateプラグインはdoWithSpring
クロージャで以下を行っています:
if (manager?.hasGrailsPlugin("controllers")) { openSessionInViewInterceptor(OpenSessionInViewInterceptor) { flushMode = HibernateAccessor.FLUSH_MANUAL sessionFactory = sessionFactory } grailsUrlHandlerMapping.interceptors << openSessionInViewInterceptor }
OpenSessionInViewInterceptor
if the controllers
plugin has been loaded. The manager
variable is an instance of the GrailsPluginManager interface and it provides methods to interact with other plugins.ここではHibernateプラグインは、controllers
プラグインがロードされてれば、OpenSessionInViewInterceptor
だけを登録します。manager
変数はGrailsPluginManagerインターフェースのインスタンスであり、他のプラグインと相互作用するためのメソッドを提供しています。
loadBefore
property to specify one or more plugins that your plugin should load before:loadBefore
プロパティには、あなたのプラグインの前にロードしておかなければならない1個以上のプラグインを指定します。
def loadBefore = ['rabbitmq']
スコープと環境
制御できるのはプラグインのロード順だけではありません。プラグインがどの環境にロードされるか、あるいはどのスコープ(ビルドの各段階)でロードされるかを指定することもできます。やり方は、それぞれのプロパティをプラグインディスクリプタ中に宣言するだけです。
def environments = ['development', 'test', 'myCustomEnv'] def scopes = [excludes:'war']
development-only
plugins to not be packaged for production use.この例では、プラグインは「development」と「test」環境のときだけロードされます。また、warフェイズからは除外設定されているので、WARファイル中にはパッケージされません。こうすることで、development-only
のプラグインは、実運用時にはパッケージされないようにできます。
利用可能なスコープの全てのリストはenum BuildScopeで定義されていますが、以下はその抜粋です:
*test
- when running tests *functional-test
- when running functional tests *run
- for run-app and run-war *war
- when packaging the application as a WAR file *all
- plugin applies to all scopes (default)
test
- テスト実行時functional-test
- ファンクショナルテスト実行時run
- run-appもしくはrun-war時war
- アプリケーションがWARファイルにパッケージ化されたときall
- 全てのスコープに適用されるプラグイン(デフォルト)
いずれのプロパティにも以下のうち1つを設定することができます。
- a string - a sole inclusion
- a list - a list of environments or scopes to include
- a map - for full control, with 'includes' and/or 'excludes' keys that can have string or list values
- a string - 1つ含む
- a list - 含められるべき環境もしくはスコープのリスト
- a map - 全ての制御。キーは'includes'か'excludes'で、バリューは文字列もしくはリスト
例えば、
def environments = "test"
という指定の場合、テスト環境のみでプラグインが含められます。これに対して
def environments = ["development", "test"]
はdevelopment と test環境の両方を含みます。最後に
def environments = [includes: ["development", "test"]]
も同様の意味です。
15.11 アーテファクトAPI
これまでの説明で、Grailsにはアーテファクトという概念があることが理解できたと思います。アーテファクトは特別なクラス型であり、通常のGroovyやJavaクラスとは異なるやり方で処理されます。例えば、プロパティやメソッドを追加することで拡張できます。アーテファクトの例は、ドメインクラスやコントローラです。気づいていなかったかもしれませんが、Grailsはアプリケーションやプラグイン開発者が、アーテファクトのための下位層のインフラストラクチャにアクセスすることを許しています。これが意味するのは、どんなアーテファクトが利用可能であるかを調べたり、あるいはそれらを拡張したりすることができるということです。また、あなた独自のカスタムアーテファクト型を追加することさえも可能です。
15.11.1 使用可能なアーテファクトの検索
searchable
properties and index the appropriate ones. So how does it do it? The answer lies with the grailsApplication
object, and instance of GrailsApplication that's available automatically in controllers and GSPs and can be injected everywhere else.プラグイン開発者からすると、アプリケーションにおいて、どのドメインクラス・コントローラや他のアーテファクトが利用可能かが分かる、ということが重要かもしれません。
例えば、Searchableプラグインは、インデックス化すべきであることを指定するsearchable
プロパティをチェックするために、どんなドメインクラスが存在しているかをまず知る必要があります。では、どんなふうにチェックできるのでしょう? 答えはgrailsApplication
オブジェクトとGrailsApplicationのインスタンスにあります。これらはコントローラとGSP中では自動的に利用可能となり、他の任意の場所で注入しておくことができます。
grailsApplication
object has several important properties and methods for querying artefacts. Probably the most common is the one that gives you all the classes of a particular artefact type:grailsApplication
オブジェクトは、アーテファクトを検索するためのいくつかの重要なプロパティとメソッドを保持しています。
for (cls in grailsApplication.<artefactType>Classes) {
…
}
artefactType
is the property name form of the artefact type. With core Grails you have:この場合、artefactType
は、プロパティ名中でアーテファクト型を指定する形式であり、Grailsコアでは以下が指定できます:
- domain
- controller
- tagLib
- service
- codec
- bootstrap
- urlMappings
例えば、繰り返し処理をすべてのドメインクラスについてしたいならば、以下を使います:
for (cls in grailsApplication.domainClasses) {
…
}
URLマッピングの場合なら以下です:
for (cls in grailsApplication.urlMappingsClasses) {
…
}
Class
:これらのプロパティが返すのはクラス(java.lang.Class)のインスタンスではないことに留意する必要があります。そうではなく、これらはGrailsClassのインスタンスであり、下位のClass
型用のものも含め、以下のような便利なプロパティやメソッドが利用可能です。
shortName
- the class name of the artefact without the package (equivalent ofClass.simpleName
).logicalPropertyName
- the artefact name in property form without the 'type' suffix. SoMyGreatController
becomes 'myGreat'.isAbstract()
- a boolean indicating whether the artefact class is abstract or not.getPropertyValue(name)
- returns the value of the given property, whether it's a static or an instance one. This works best if the property is initialised on declaration, e.g.static transactional = true
.
shortName
- パッケージ部分を除いたアーテファクトのクラス名(Class.simpleName
と等価)logicalPropertyName
- プロパティ中で用いられる名アーテファクトの名前から型接尾辞を除いたもの。MyGreatController
は「myGreat」になる。isAbstract()
- アーテファクトクラスがabstractかどうかを表すブーリアン値getPropertyValue(name)
- 指定したプロパティ値を、staticか非staticかどうかに関わらず返す。もしプロパティが「static transactional = true
」のように初期化されて宣言されていたときにも動作する。
アーテファクトAPIで、クラスを名前で取得したり、指定したクラスがアーテファクトかどうかを判断したりすることができます:
- get<type>Class(String name)
- is<type>Class(Class clazz)
GrailsClass
instance for the given name, e.g. 'MyGreatController'. The second will check whether a class is a particular type of artefact. For example, you can use grailsApplication.isControllerClass(org.example.MyGreatController)
to check whether MyGreatController
is in fact a controller.最初のメソッドは、指定した名前、たとえば「MyGreatController」からGrailsClass
インスタンスを取得します。二番目のメソッドは、クラスが特定のアーテファクトの型かどうかを判断します。例えば、grailsApplication.isControllerClass(org.example.MyGreatController)
とすることで、MyGreatController
がコントローラかどうかをチェックすることができます。
15.11.2 アーテファクト型の追加
ArtefactHandler
implementation and register it in your main plugin class:プラグインでは、どんな実装が利用できるかわかり、自動リロードの過程に組込むことができるような、自分自身のアーテファクトを簡単に提供することができます。そのためにやるべきことは、ArtefactHandler
の実装を生成し、メインのプラグインクラス中に登録しておくことだけです:
class MyGrailsPlugin { def artefacts = [ org.somewhere.MyArtefactHandler ] … }
artefacts
list can contain either handler classes (as above) or instances of handlers.リストartefacts
は、ハンドラクラス(上述)もしくはハンドラの一連のインスタンスを保持することができます。
それでは、アーテファクトハンドラは、どのようなものでしょうか?ここでは単にArtefactHandlerインターフェースを実装するものということにしておきます。利便のため、extendsすればすぐ使えるスケルトン実装ArtefactHandlerAdapterも用意されています。
ハンドラそれ自身に加えて、新しいアーテファクトは、GrailsClassをimplementsする対応するラッパークラスを必要とします。こちらもAbstractInjectableGrailsClassなどのスケルトン実装が利用可能です。これはあなたのアーテファクトを、コントローラやサービスのようにオートワイヤ可能なSpringビーンにしてくれるので特に便利でしょう。
ハンドラとラッパーの動作を理解するのにベストなやり方は、Quartz pluginのコードを読んでみることです:
他の例としては、Shiroプラグインがあり、こちらはrealmアーテファクトを追加します。
15.12 バイナリープラグイン
- Binary plugins can be published as standard JAR files to a Maven repository
- Binary plugins can be declared like any other JAR dependency
- Commercial plugins are more viable since the source isn't published
- IDEs have a better understanding since binary plugins are regular JAR files containing classes
- Mavenリポジトリで通常のJARファイルで配布可能。
- バイナリプラグインは他のJARと同じように依存管理が行える。
- ソースコードを公開しない商用プラグインが可能
- 通常のJARになることによって、IDE等の環境で扱いやすくなる
パッケージング Packaging
--binary
flag:--binary
フラグを使用します
grails package-plugin --binary
- Grails artifact classes such as controllers, domain classes and so on
- I18n Message bundles
- GSP Views, layouts and templates
- コントローラ、ドメイン等のGrailsのアーテファクトクラス
- I18nメッセージファイル
- GSPビュー、レイアウト、テンプレート
def packaging = "binary"
バイナリプラグイン使用方法 Using Binary Plugins
target
directory of the plugin, for example target/foo-plugin-0.1.jar
. There are two ways to incorporate a binary plugin into an application.targrt
ディレクトリに生成されます。例としてtarget/foo-plugin-0.1.jar
。 バイナリプラグインを使用するには2つの方法があります。
lib
directory. The other is to publish the plugin JAR to a compatible Maven repository and declare it as a dependency in grails-app/conf/BuildConfig.groovy
:lib
ディレクトリに配置。もう一つの方法は、Mavenリポジトリに配備して、grails-app/conf/BuildConfig.groovy
に依存定義を行います。
dependencies {
compile "mycompany:myplugin:0.1"
}
Since binary plugins are packaged as JAR files, they are declared as dependencies in theバイナリプラグインは依存定義をdependencies
block, not in theplugins
block as you may be naturally inclined to do. Theplugins
block is used for declaring traditional source plugins packaged as zip filesdependencies
ブロックに記述します。plugins
ブロックは今までのソースコードがzipされたプラグインで使用します。