You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@buildr.apache.org by as...@apache.org on 2008/01/09 08:12:19 UTC
svn commit: r610283 - in /incubator/buildr/trunk: CHANGELOG
doc/pages/packaging.textile lib/java/packaging.rb lib/tasks/zip.rb
spec/compile_spec.rb spec/java_packaging_spec.rb spec/packaging_helper.rb
Author: assaf
Date: Tue Jan 8 23:12:18 2008
New Revision: 610283
URL: http://svn.apache.org/viewvc?rev=610283&view=rev
Log:
Added: EAR packaging (Victor Hugo Borja)
Modified:
incubator/buildr/trunk/CHANGELOG
incubator/buildr/trunk/doc/pages/packaging.textile
incubator/buildr/trunk/lib/java/packaging.rb
incubator/buildr/trunk/lib/tasks/zip.rb
incubator/buildr/trunk/spec/compile_spec.rb
incubator/buildr/trunk/spec/java_packaging_spec.rb
incubator/buildr/trunk/spec/packaging_helper.rb
Modified: incubator/buildr/trunk/CHANGELOG
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/CHANGELOG?rev=610283&r1=610282&r2=610283&view=diff
==============================================================================
--- incubator/buildr/trunk/CHANGELOG (original)
+++ incubator/buildr/trunk/CHANGELOG Tue Jan 8 23:12:18 2008
@@ -3,6 +3,7 @@
* Added: To run all test cases 'rake spec'. Test coverage reports will show up in html/coverage. To run failing tests against, 'rake failing'.
* Added: Layout class for controlling the project layout. Also cleaned up places where paths were used instead of path names.
* Added: HTTP Basic authentication support (Yuen-Chi Lian).
+* Added: EAR packaging (Victor Hugo Borja).
* Changed: Upgraded to Rake 0.8 and RSpec 1.1.
* Changed: Resources are now copied to target/resources instead of target/classes, and target/test/resources instead of target/test-resources.
* Changed: Test cases are not compiled into target/test/classes instead of target/test-classes.
Modified: incubator/buildr/trunk/doc/pages/packaging.textile
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/doc/pages/packaging.textile?rev=610283&r1=610282&r2=610283&view=diff
==============================================================================
--- incubator/buildr/trunk/doc/pages/packaging.textile (original)
+++ incubator/buildr/trunk/doc/pages/packaging.textile Tue Jan 8 23:12:18 2008
@@ -271,6 +271,84 @@
}}}
+h2. Packaging EARs
+
+EAR packaging is slightly different from JAR/WAR packaging. It's main purpose
+is to package components together, and so it includes special methods for
+handling component inclusion that take care to update application.xml and the
+component's classpath.
+
+EAR packages support four component types:
+
+* @:war@ -- J2EE Web Application (WAR).
+* @:ejb@ -- Enterprise Java Bean (JAR).
+* @:jar@ -- J2EE Application Client (JAR).
+* @:lib@ -- Shared library (JAR).
+
+This example shows two ways for adding components built by other projects:
+
+{{{!ruby
+package(:ear) << project('coolWebService').package(:war)
+package(:ear).add project('commonLib') # By default, the JAR package
+}}}
+
+Adding a WAR package assumes it's a WAR component and treats it as such, but
+JAR packages can be any of three component types, so by default they are all
+treated as shared libraries. If you want to add an EJB or Application Client
+component, you need to say so explicitly, either passing @type=>package@, or by
+passing the component type in the @:type@ option.
+
+Here are three examples:
+
+{{{!ruby
+# Assumed to be a shared library.
+package(:ear).add 'org.springframework:spring:jar:2.6'
+# Component type mapped to package.
+package(:ear).add :ejb=>project('beanery')
+# Adding component with specific package type.
+package(:ear).add project('client'), :type=>:jar
+}}}
+
+By default, WAR components are all added under the @/war@ path, and likewise,
+EJB components are added under the @/ejb@ path, shared libraries under @/lib@
+and Application Client components under @/jar@.
+
+If you want to place components in different locations you can do so using the
+@:path@ option, or by specifying a different mapping between component type and
+its path. The following two examples are equivalent:
+
+{{{!ruby
+# Specify once per component.
+package(:ear).add project('coolWebService').package(:war), :path=>'coolServices'
+# Configure once and apply to all added components.
+package(:ear).map[:war] = 'coolServices'
+package(:ear) << project('coolWebService').package(:war)
+}}}
+
+EAR packages include an @application.xml@ file in the @META-INF@ directory that
+describes the application and its component. This file is created for you
+during packaging, by referencing all the components added to the EAR. There
+are a couple of things you will typically want to change.
+
+* *display-name* -- The application's display name defaults to the project's
+identifier. You can change that by setting the @display_name@ attribute.
+
+* *context-root* -- WAR components specify a context root, based on the package
+identifier, for example, "cool-web-1.0.war" will have the context root
+"cool-web". To specify a different context root, add the WAR package with the
+@context_root@ option.
+
+Again, by example:
+
+{{{!ruby
+package(:ear).display_name = 'MyCoolWebService'
+package(:ear).add project('coolWebService').package(:war), :context-root=>'coolness'
+}}}
+
+If you need to disable the context root (e.g. for Portlets), set @context_root@
+to @false@.
+
+
h2. Packaging Tars and GZipped Tars
Everything you know about working with ZIP files translates to Tar files, the
Modified: incubator/buildr/trunk/lib/java/packaging.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/java/packaging.rb?rev=610283&r1=610282&r2=610283&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/java/packaging.rb (original)
+++ incubator/buildr/trunk/lib/java/packaging.rb Tue Jan 8 23:12:18 2008
@@ -29,12 +29,13 @@
initialize_without_manifest *args
@manifest = false
@meta_inf = []
+ @dependencies = FileList[]
prepare do
@prerequisites << manifest if String === manifest || Rake::Task === manifest
[meta_inf].flatten.map { |file| file.to_s }.uniq.each { |file| path('META-INF').include file }
end
-
+
enhance do
if manifest
# Tempfiles gets deleted on garbage collection, so we're going to hold on to it
@@ -125,6 +126,7 @@
end
+
# Extends the JarTask to create a WAR file.
#
# Supports all the same options as JarTask, in additon to these two options:
@@ -163,6 +165,7 @@
end
+
# Extends the JarTask to create an AAR file (Axis2 service archive).
#
# Supports all the same options as JarTask, with the addition of :wsdls, :services_xml and :libs.
@@ -209,6 +212,205 @@
end
+ # Extend the JarTask to create an EAR file.
+ #
+ # The following component types are supported by the EARTask:
+ #
+ # * :war -- A J2EE Web Application
+ # * :ejb -- An Enterprise Java Bean
+ # * :jar -- A J2EE Application Client.[1]
+ # * :lib -- An ear scoped shared library[2] (for things like logging,
+ # spring, etc) common to the ear components
+ #
+ # The EarTask uses the "Mechanism 2: Bundled Optional Classes" as described on [2].
+ # All specified libraries are added to the EAR archive and the Class-Path manifiest entry is
+ # modified for each EAR component. Special care is taken with WebApplications, as they can
+ # contain libraries on their WEB-INF/lib directory, libraries already included in a war file
+ # are not referenced by the Class-Path entry of the war in order to avoid class collisions
+ #
+ # EarTask supports all the same options as JarTask, in additon to these two options:
+ #
+ # * :display_name -- The displayname to for this ear on application.xml
+ #
+ # * :map -- A Hash used to map component type to paths within the EAR.
+ # By default each component type is mapped to a directory with the same name,
+ # for example, EJBs are stored in the /ejb path. To customize:
+ # package(:ear).dirs[:war] = 'web-applications'
+ # package(:ear).dirs[:lib] = nil # store shared libraries on root of archive
+ #
+ # EAR components are added by means of the EarTask#add, EarTask#<<, EarTask#push methods
+ # Component type is determined from the artifact's type.
+ #
+ # package(:ear) << project('coolWebService').package(:war)
+ #
+ # The << method is just an alias for push, with the later you can add multiple components
+ # at the same time. For example..
+ #
+ # package(:ear).push 'org.springframework:spring:jar:2.6',
+ # projects('reflectUtils', 'springUtils'),
+ # project('coolerWebService').package(:war)
+ #
+ # The add method takes a single component with an optional hash. You can use it to override
+ # some component attributes.
+ #
+ # You can override the component type for a particular artifact. The following example
+ # shows how you can tell the EarTask to treat a JAR file as an EJB:
+ #
+ # # will add an ejb entry for the-cool-ejb-2.5.jar in application.xml
+ # package(:ear).add 'org.coolguys:the-cool-ejb:jar:2.5', :type=>:ejb
+ # # A better syntax for this is:
+ # package(:ear).add :ejb=>'org.coolguys:the-cool-ejb:jar:2.5'
+ #
+ # By default, every JAR package is assumed to be a library component, so you need to specify
+ # the type when including an EJB (:ejb) or Application Client JAR (:jar).
+ #
+ # For WebApplications (:war)s, you can customize the context-root that appears in application.xml.
+ # The following example also specifies a different directory inside the EAR where to store the webapp.
+ #
+ # package(:ear).add project(:remoteService).package(:war),
+ # :path => 'web-services', :context_root => '/Some/URL/Path'
+ #
+ # [1] http://java.sun.com/j2ee/sdk_1.2.1/techdocs/guides/ejb/html/Overview5.html#10106
+ # [2] http://java.sun.com/j2ee/verified/packaging.html
+ class EarTask < JarTask
+
+ SUPPORTED_TYPES = [:war, :ejb, :jar, :rar, :lib]
+
+ # The display-name entry for application.xml
+ attr_accessor :display_name
+ # Map from component type to path inside the EAR.
+ attr_accessor :map
+
+ def initialize(*args)
+ super
+ @map = Hash.new { |h, k| k.to_s }
+ @libs, @components = [], []
+ prepare do
+ @components.each do |component|
+ path(component[:path]).include(component[:artifact])
+ end
+ path('META-INF').include(descriptor)
+ end
+ end
+
+ # Add an artifact to this EAR.
+ def add(*args)
+ options = Hash === args.last ? args.pop.clone : {}
+ if artifact = args.shift
+ type = options[:type]
+ unless type
+ type = artifact.respond_to?(:type) ? artifact.type : artifact.pathmap('%x').to_sym
+ type = :lib if type == :jar
+ raise "Unknown EAR component type: #{type}. Perhaps you may explicity tell what component type to use." unless
+ SUPPORTED_TYPES.include?(type)
+ end
+ else
+ type = SUPPORTED_TYPES.find { |type| options[type] }
+ artifact = Buildr.artifact(options[type])
+ end
+
+ component = options.merge(:artifact=>artifact, :type=>type,
+ :id=>artifact.respond_to?(:to_spec) ? artifact.id : artifact.to_s.pathmap('%n'),
+ :path=>options[:path] || map[type].to_s)
+ file(artifact.to_s).enhance do |task|
+ task.enhance { |task| update_classpath(task.name) }
+ end unless :lib == type
+ @components << component
+ self
+ end
+
+ def push(*artifacts)
+ artifacts.flatten.each { |artifact| add artifact }
+ self
+ end
+ alias_method :<<, :push
+
+ protected
+
+ def associate(project)
+ @project = project
+ end
+
+ def path_to(*args) #:nodoc:
+ @project.path_to(:target, :ear, *args)
+ end
+ alias_method :_, :path_to
+
+ def update_classpath(package)
+ Zip::ZipFile.open(package) do |zip|
+ # obtain the manifest file
+ manifest = zip.read('META-INF/MANIFEST.MF').split("\n\n")
+ manifest.first.gsub!(/([^\n]{71})\n /,"\\1")
+ manifest.first << "Class-Path: \n" unless manifest.first =~ /Class-Path:/
+ # Determine which libraries are already included.
+ included_libs = manifest.first[/^Class-Path:\s+(.*)$/, 1].split(/\s+/).map { |fn| File.basename(fn) }
+ included_libs += zip.entries.map(&:to_s).select { |fn| fn =~ /^WEB-INF\/lib\/.+/ }.map { |fn| File.basename(fn) }
+ # Include all other libraries in the classpath.
+ libs_classpath.reject { |path| included_libs.include?(File.basename(path)) }.each do |path|
+ manifest.first.sub!(/^Class-Path:/, "\\0 #{path}\n ")
+ end
+
+ Tempfile.open 'MANIFEST.MF' do |temp|
+ temp.write manifest.join("\n\n")
+ temp.flush
+ # Update the manifest.
+ if Buildr::Java.jruby?
+ Buildr.ant("update-jar") do |ant|
+ ant.jar :destfile => task.name, :manifest => temp.path,
+ :update => 'yes', :whenmanifestonly => 'create'
+ end
+ else
+ zip.replace('META-INF/MANIFEST.MF', temp.path)
+ end
+ end
+ end
+ end
+
+ private
+
+ # Classpath of all packages included as libraries (type :lib).
+ def libs_classpath
+ @classpath = @components.select { |comp| comp[:type] == :lib }.
+ map { |comp| File.expand_path(File.join(comp[:path], File.basename(comp[:artifact].to_s)), '/')[1..-1] }
+ end
+
+ # return a FileTask to build the ear application.xml file
+ def descriptor
+ @descriptor ||= file('META-INF/application.xml') do |task|
+ mkpath File.dirname(task.name), :verbose=>false
+ File.open task.name, 'w' do |file|
+ xml = Builder::XmlMarkup.new(:target=>file, :indent => 2)
+ xml.declare! :DOCTYPE, :application, :PUBLIC,
+ "-//Sun Microsystems, Inc.//DTD J2EE Application 1.2//EN",
+ "http://java.sun.com/j2ee/dtds/application_1_2.dtd"
+ xml.application do
+ xml.tag! 'display-name', display_name
+ @components.each do |comp|
+ uri = File.expand_path(File.join(comp[:path], File.basename(comp[:artifact].to_s)), '/')[1..-1]
+ case comp[:type]
+ when :war
+ xml.module :id=>comp[:id] do
+ xml.web do
+ xml.tag! 'web-uri', uri
+ xml.tag! 'context-root', File.join('', (comp[:context_root] || comp[:id])) unless comp[:context_root] == false
+ end
+ end
+ when :ejb
+ xml.module :id=>comp[:id] do
+ xml.ejb uri
+ end
+ when :jar
+ xml.jar uri
+ end
+ end
+ end
+ end
+ end
+ end
+
+ end
+
+
include Extension
before_define do |project|
@@ -319,6 +521,13 @@
aar.with compile.target unless compile.sources.empty?
aar.with resources.target unless resources.sources.empty?
aar.with :libs=>compile.dependencies
+ end
+ end
+
+ def package_as_ear(file_name) #:nodoc:
+ Java::Packaging::EarTask.define_task(file_name).tap do |ear|
+ ear.send :associate, self
+ ear.with :display_name=>id, :manifest=>manifest, :meta_inf=>meta_inf
end
end
Modified: incubator/buildr/trunk/lib/tasks/zip.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/tasks/zip.rb?rev=610283&r1=610282&r2=610283&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/tasks/zip.rb (original)
+++ incubator/buildr/trunk/lib/tasks/zip.rb Tue Jan 8 23:12:18 2008
@@ -73,6 +73,7 @@
self
end
alias :add :include
+ alias :<< :include
# :call-seq:
# exclude(*files) => self
@@ -175,6 +176,7 @@
@includes |= files
self
end
+ alias :<< :include
def exclude(*files)
@excludes |= files
@@ -264,6 +266,7 @@
self
end
alias :add :include
+ alias :<< :include
# :call-seq:
# exclude(*files) => self
Modified: incubator/buildr/trunk/spec/compile_spec.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/spec/compile_spec.rb?rev=610283&r1=610282&r2=610283&view=diff
==============================================================================
--- incubator/buildr/trunk/spec/compile_spec.rb (original)
+++ incubator/buildr/trunk/spec/compile_spec.rb Tue Jan 8 23:12:18 2008
@@ -353,6 +353,13 @@
suppress_stdout { compile_task.from('failed.java').invoke rescue nil }
File.stat(compile_task.target.to_s).mtime.should be_close(Time.now - 10, 2)
end
+
+ it 'should complain if source directories and no compiler selected' do
+ mkpath 'sources'
+ define 'bar' do
+ lambda { compile.from('sources').invoke }.should raise_error(RuntimeError, /no compiler selected/i)
+ end
+ end
end
Modified: incubator/buildr/trunk/spec/java_packaging_spec.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/spec/java_packaging_spec.rb?rev=610283&r1=610282&r2=610283&view=diff
==============================================================================
--- incubator/buildr/trunk/spec/java_packaging_spec.rb (original)
+++ incubator/buildr/trunk/spec/java_packaging_spec.rb Tue Jan 8 23:12:18 2008
@@ -245,7 +245,7 @@
def inspect_meta_inf
package = project('foo').package(@packaging)
package.invoke
- assumed = Array(@meta_inf)
+ assumed = Array(@meta_inf_ignore)
Zip::ZipFile.open(package.to_s) do |zip|
entries = zip.entries.map(&:to_s).select { |f| File.dirname(f) == 'META-INF' }.map { |f| File.basename(f) }
assumed.each { |f| entries.should include(f) }
@@ -314,7 +314,7 @@
before { @packaging = :jar }
it_should_behave_like 'package with manifest'
it_should_behave_like 'package with meta_inf'
- before { @meta_inf = ['MANIFEST.MF'] }
+ before { @meta_inf_ignore = 'MANIFEST.MF' }
it 'should use files from compile directory if nothing included' do
write 'src/main/java/Test.java', 'class Test {}'
@@ -368,7 +368,7 @@
before { @packaging = :war }
it_should_behave_like 'package with manifest'
it_should_behave_like 'package with meta_inf'
- before { @meta_inf = ['MANIFEST.MF'] }
+ before { @meta_inf_ignore = 'MANIFEST.MF' }
def make_jars
artifact('group:id:jar:1.0') { |t| write t.to_s }
@@ -465,9 +465,10 @@
before { @packaging = :aar }
it_should_behave_like 'package with manifest'
it_should_behave_like 'package with meta_inf'
- before { @meta_inf = ['MANIFEST.MF', 'services.xml'] }
-
- setup { write 'src/main/axis2/services.xml' }
+ before do
+ write 'src/main/axis2/services.xml'
+ @meta_inf_ignore = ['MANIFEST.MF', 'services.xml']
+ end
def make_jars
artifact('group:id:jar:1.0') { |t| write t.to_s }
@@ -538,6 +539,291 @@
project('foo').package(:aar).libs.should include(artifact('additional:id:jar:1.0'))
end
+end
+
+
+describe Packaging, 'ear' do
+ it_should_behave_like 'packaging'
+ before { @packaging = :ear }
+ it_should_behave_like 'package with manifest'
+ it_should_behave_like 'package with meta_inf'
+ before { @meta_inf_ignore = ['MANIFEST.MF', 'application.xml'] }
+
+ def inspect_ear
+ project('foo').package(:ear).invoke
+ Zip::ZipFile.open(project('foo').package(:ear).to_s) do |ear|
+ yield ear.entries.map(&:to_s).sort
+ end
+ end
+
+ def inspect_application_xml
+ project('foo').package(:ear).invoke
+ Zip::ZipFile.open(project('foo').package(:ear).to_s) do |ear|
+ yield REXML::Document.new(ear.read('META-INF/application.xml')).root
+ end
+ end
+
+ def inspect_classpath(package)
+ project('foo').package(:ear).invoke
+ Zip::ZipFile.open(project('foo').package(:ear).to_s) do |ear|
+ File.open('tmp.zip', 'w') do |tmp|
+ tmp.write ear.file.read(package)
+ end
+ Zip::ZipFile.open('tmp.zip') do |zip|
+ first_section = zip.file.read('META-INF/MANIFEST.MF').split("\n\n").first.
+ split("\n").each { |line| line.length.should < 72 }.
+ inject([]) { |merged, line|
+ if line[0] == 32
+ merged.last << line[1..-1]
+ else
+ merged << line
+ end
+ merged
+ }.map { |line| line.split(/: /) }.
+ inject({}) { |map, (name, value)| map.merge(name=>value) }
+ yield first_section['Class-Path'].to_s.split(' ')
+ end
+ end
+ end
+
+ it 'should set display name from project id' do
+ define 'foo', :version=>'1.0' do
+ package(:ear).display_name.should eql('foo')
+ define 'bar' do
+ package(:ear).display_name.should eql('foo-bar')
+ end
+ end
+ end
+
+ it 'should set display name in application.xml' do
+ define 'foo', :version=>'1.0' do
+ package(:ear)
+ end
+ inspect_application_xml { |xml| xml.get_text('/application/display-name').should == 'foo' }
+ end
+
+ it 'should accept different display name' do
+ define 'foo', :version=>'1.0' do
+ package(:ear).display_name = 'bar'
+ end
+ inspect_application_xml { |xml| xml.get_text('/application/display-name').should == 'bar' }
+ end
+
+ it 'should map WARs to /war directory' do
+ define 'foo', :version=>'1.0' do
+ package(:ear) << package(:war)
+ end
+ inspect_ear { |files| files.should include('war/foo-1.0.war') }
+ end
+
+ it 'should map EJBs to /ejb directory' do
+ define 'foo', :version=>'1.0' do
+ package(:ear).add :ejb=>package(:jar)
+ end
+ inspect_ear { |files| files.should include('ejb/foo-1.0.jar') }
+ end
+
+ it 'should map JARs to /lib directory' do
+ define 'foo', :version=>'1.0' do
+ package(:ear) << package(:jar)
+ end
+ inspect_ear { |files| files.should include('lib/foo-1.0.jar') }
+ end
+
+ it 'should accept component type with :type option' do
+ define 'foo', :version=>'1.0' do
+ package(:ear).add package(:jar), :type=>:ejb
+ end
+ inspect_ear { |files| files.should include('ejb/foo-1.0.jar') }
+ end
+
+ it 'should accept component and its type as type=>artiract' do
+ define 'foo', :version=>'1.0' do
+ package(:ear).add :ejb=>package(:jar)
+ end
+ inspect_ear { |files| files.should include('ejb/foo-1.0.jar') }
+ end
+
+ it 'should map typed JARs to /jar directory' do
+ define 'foo', :version=>'1.0' do
+ package(:ear).add :jar=>package(:jar)
+ end
+ inspect_ear { |files| files.should include('jar/foo-1.0.jar') }
+ end
+
+ it 'should complain about unknown component type' do
+ define 'foo', :version=>'1.0' do
+ lambda { package(:ear).add package(:zip) }.should raise_error(RuntimeError, /unknown ear component type/i)
+ end
+ end
+
+ it 'should allow unknown component types with explicit type' do
+ define 'foo', :version=>'1.0' do
+ package(:ear).add :lib=>package(:zip)
+ end
+ inspect_ear { |files| files.should include('lib/foo-1.0.zip') }
+ end
+
+ it 'should accept alternative directory name' do
+ define 'foo', :version=>'1.0' do
+ package(:ear).add package(:jar), :path=>'trash'
+ end
+ inspect_ear { |files| files.should include('trash/foo-1.0.jar') }
+ end
+
+ it 'should accept customization of directory map' do
+ define 'foo', :version=>'1.0' do
+ package(:ear).map[:jar] = 'jarred'
+ package(:ear).add :jar=>package(:jar)
+ end
+ inspect_ear { |files| files.should include('jarred/foo-1.0.jar') }
+ end
+
+ it 'should accept customization of directory map with nil paths in application.xml' do
+ define 'foo', :version=>'1.0' do
+ package(:ear).map[:war] = nil
+ package(:ear).add :war=>package(:war)
+ package(:ear).add package(:jar)
+ end
+ inspect_ear { |files| files.should include('foo-1.0.war') }
+ inspect_application_xml do |xml|
+ xml.get_text("/application/module[@id='foo']/web/web-uri").to_s.should eql('foo-1.0.war')
+ end
+ end
+
+ it 'should accept customization of directory map with nil paths in the classpath' do
+ define 'foo', :version=>'1.0' do
+ package(:ear).map[:lib] = nil
+ package(:ear).add :war=>package(:war)
+ package(:ear) << package(:jar)
+ end
+ inspect_classpath 'war/foo-1.0.war' do |classpath|
+ classpath.should include('foo-1.0.jar')
+ end
+ end
+
+ it 'should list WAR components in application.xml' do
+ define 'foo', :version=>'1.0' do
+ package(:ear) << package(:war) << package(:war, :id=>'bar')
+ end
+ inspect_application_xml do |xml|
+ xml.get_elements("/application/module[@id='foo'][web]").should_not be_empty
+ xml.get_elements("/application/module[@id='bar'][web]").should_not be_empty
+ end
+ end
+
+ it 'should specify web-uri for WAR components in application.xml' do
+ define 'foo', :version=>'1.0' do
+ package(:ear) << package(:war)
+ package(:ear).add package(:war, :id=>'bar'), :path=>'ws'
+ end
+ inspect_application_xml do |xml|
+ xml.get_text("/application/module[@id='foo']/web/web-uri").to_s.should eql('war/foo-1.0.war')
+ xml.get_text("/application/module[@id='bar']/web/web-uri").to_s.should eql('ws/bar-1.0.war')
+ end
+ end
+
+ it 'should specify context-root for WAR components in application.xml' do
+ define 'foo', :version=>'1.0' do
+ package(:ear) << package(:war)
+ package(:ear).add package(:war, :id=>'bar')
+ end
+ inspect_application_xml do |xml|
+ xml.get_text("/application/module[@id='foo']/web/context-root").to_s.should eql('/foo')
+ xml.get_text("/application/module[@id='bar']/web/context-root").to_s.should eql('/bar')
+ end
+ end
+
+ it 'should accept context-root for WAR components in application.xml' do
+ define 'foo', :version=>'1.0' do
+ package(:ear).add package(:war), :context_root=>'rooted'
+ end
+ inspect_application_xml do |xml|
+ xml.get_text("/application/module[@id='foo']/web/context-root").to_s.should eql('/rooted')
+ end
+ end
+
+ it 'should allow disabling the context root' do
+ define 'foo', :version=>'1.0' do
+ package(:ear).add package(:war), :context_root=>false
+ end
+ inspect_application_xml do |xml|
+ xml.get_elements("/application/module[@id='foo']/web/context-root").should be_empty
+ end
+ end
+
+ it 'should list EJB components in application.xml' do
+ define 'foo', :version=>'1.0' do
+ package(:ear).add :ejb=>package(:jar)
+ package(:ear).add :ejb=>package(:jar, :id=>'bar')
+ end
+ inspect_application_xml do |xml|
+ xml.get_text("/application/module[@id='foo']/ejb").to_s.should eql('ejb/foo-1.0.jar')
+ xml.get_text("/application/module[@id='bar']/ejb").to_s.should eql('ejb/bar-1.0.jar')
+ end
+ end
+
+ it 'should list JAR components in application.xml' do
+ define 'foo', :version=>'1.0' do
+ package(:ear) << { :jar=>package(:jar) } << { :jar=>package(:jar, :id=>'bar') }
+ end
+ inspect_application_xml do |xml|
+ jars = xml.get_elements('/application/jar').map(&:texts).map(&:to_s)
+ jars.should include('jar/foo-1.0.jar', 'jar/bar-1.0.jar')
+ end
+ end
+
+ it 'should update WAR component classpath to include libraries' do
+ define 'foo', :version=>'1.0' do
+ package(:ear) << package(:jar, :id=>'lib1') << package(:jar, :id=>'lib2')
+ package(:ear).add package(:war)
+ end
+ inspect_classpath 'war/foo-1.0.war' do |classpath|
+ classpath.should include('lib/lib1-1.0.jar', 'lib/lib2-1.0.jar')
+ end
+ end
+
+ it 'should update WAR component classpath but skip internal libraries' do
+ define 'foo', :version=>'1.0' do
+ package(:ear) << package(:jar, :id=>'lib1') << package(:jar, :id=>'lib2')
+ package(:war).with(:libs=>package(:jar, :id=>'lib1'))
+ package(:ear).add package(:war)
+ end
+ inspect_classpath 'war/foo-1.0.war' do |classpath|
+ classpath.should_not include('lib/lib1-1.0.jar')
+ classpath.should include('lib/lib2-1.0.jar')
+ end
+ end
+
+ it 'should update EJB component classpath to include libraries' do
+ define 'foo', :version=>'1.0' do
+ package(:ear) << package(:jar, :id=>'lib1') << package(:jar, :id=>'lib2')
+ package(:ear).add :ejb=>package(:jar)
+ end
+ inspect_classpath 'ejb/foo-1.0.jar' do |classpath|
+ classpath.should include('lib/lib1-1.0.jar', 'lib/lib2-1.0.jar')
+ end
+ end
+
+ it 'should update JAR component classpath to include libraries' do
+ define 'foo', :version=>'1.0' do
+ package(:ear) << package(:jar, :id=>'lib1') << package(:jar, :id=>'lib2')
+ package(:ear).add :jar=>package(:jar)
+ end
+ inspect_classpath 'jar/foo-1.0.jar' do |classpath|
+ classpath.should include('lib/lib1-1.0.jar', 'lib/lib2-1.0.jar')
+ end
+ end
+
+ it 'should deal with very long classpaths' do
+ define 'foo', :version=>'1.0' do
+ 20.times { |i| package(:ear) << package(:jar, :id=>"lib#{i}") }
+ package(:ear).add :jar=>package(:jar)
+ end
+ inspect_classpath 'jar/foo-1.0.jar' do |classpath|
+ classpath.should include('lib/lib1-1.0.jar', 'lib/lib2-1.0.jar')
+ end
+ end
end
Modified: incubator/buildr/trunk/spec/packaging_helper.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/spec/packaging_helper.rb?rev=610283&r1=610282&r2=610283&view=diff
==============================================================================
--- incubator/buildr/trunk/spec/packaging_helper.rb (original)
+++ incubator/buildr/trunk/spec/packaging_helper.rb Tue Jan 8 23:12:18 2008
@@ -45,5 +45,3 @@
end
end
end
-
-