2009-08-14 15 views
9

ich ein Java-Projekt, das mit buildr und das hat einige externen Abhängigkeiten aufgebaut ist:buildr: Paketabhängigkeiten in ein einziges Glas

repositories.remote << "http://www.ibiblio.org/maven2" 
repositories.remote << "http://packages.example/" 

define "myproject" do 
    compile.options.target = '1.5' 
    project.version = "1.0.0" 
    compile.with 'dependency:dependency-xy:jar:1.2.3' 
    compile.with 'dependency2:dependency2:jar:4.5.6' 

    package(:jar) 
end 

Ich möchte dies eine einzige Standalone-JAR-Datei erstellen, die diese Abhängigkeiten alle umfassen .

Wie mache ich das?

(es gibt eine logische Folge Frage: How can I strip all the unused code from the included dependencies and only package the classes I actually use)

Antwort

8

Dies ist, was jetzt ich tue. Dies nutzt autojar nur die notwendigen Abhängigkeiten zu ziehen:

def add_dependencies(pkg) 
    tempfile = pkg.to_s.sub(/.jar$/, "-without-dependencies.jar") 
    mv pkg.to_s, tempfile 

    dependencies = compile.dependencies.map { |d| "-C#{d}"}.join(" ") 
    sh "java -jar tools/autojar.jar -baev -o #{pkg} #{dependencies} #{tempfile}" 
end 

und später:

package(:jar) 
package(:jar).enhance { |pkg| pkg.enhance { |pkg| add_dependencies(pkg) }} 

(Einschränkung:. Ich weiß wenig über buildr, das völlig der falsche Ansatz könnte es für mich funktioniert, obwohl)

+0

Dies ist die eigentliche richtige Antwort. Meine Antwort unten fügt nur die Jars zum 'lib'-Ordner hinzu, der in Hadoop funktioniert, aber nirgendwo sonst. –

+0

Das funktioniert gut - es ist in Ordnung, die Aufgabe zu erledigen. Vielleicht wäre ein schickerer Weg diese Art von Ansatz https://gist.github.com/981589 –

0

ich werde Cascading für mein Beispiel verwenden:

cascading_dev_jars = Dir[_("#{ENV["CASCADING_HOME"]}/build/cascading-{core,xml}-*.jar")] 
#... 
package(:jar).include cascading_dev_jars, :path => "lib" 
7

ich lerne auch Buildr und zur Zeit auf diese Weise Scala Laufzeit mit meiner Anwendung ich bin Verpackung:

package(:jar).with(:manifest => _('src/MANIFEST.MF')).exclude('.scala-deps') 
    .merge('/var/local/scala/lib/scala-library.jar') 

Keine Ahnung, ob die schlechter ist als autojar (Kommentare sind willkommen), scheint aber mit einem arbeiten einfaches Beispiel. Es dauert 4,5 Minuten, um dieses scala-library.jar-Paket zu packen.

+0

das Schöne an Autojar ist, dass es auch Abhängigkeiten entfernt, die nie in Ihrem Programm verwendet werden (basierend auf Bytecode-Inspektion) - so in der Theorie Sie sollten eine kleinere Ergebnisdatei erhalten – levinalex

+2

Dies ist die richtige Antwort, da es eine Build in buildr Funktion verwendet –

+0

Ich werde das zweite; Dies ist der Weg, es mit buildr zu tun. –

0

Hier ist, wie ich ein Uberjar mit Buildr erstellen, diese Anpassung von dem, was in den Topf gelegt wird und wie das Manifest erstellt:

assembly_dir = 'target/assembly' 
main_class = 'com.something.something.Blah' 

artifacts = compile.dependencies 

artifacts.each do |artifact| 
    Unzip.new(_(assembly_dir) => artifact).extract 
end 

# remove dirs from assembly that should not be in uberjar 
FileUtils.rm_rf("#{_(assembly_dir)}/example/package") 
FileUtils.rm_rf("#{_(assembly_dir)}/example/dir") 

# create manifest file 
File.open(_("#{assembly_dir}/META-INF/MANIFEST.MF"), 'w') do |f| 
    f.write("Implementation-Title: Uberjar Example\n") 
    f.write("Implementation-Version: #{project_version}\n") 
    f.write("Main-Class: #{main_class}\n") 
    f.write("Created-By: Buildr\n")     
end 

present_dir = Dir.pwd 
Dir.chdir _(assembly_dir) 
puts "Creating #{_("target/#{project.name}-#{project.version}.jar")}" 
`jar -cfm #{_("target/#{project.name}-#{project.version}.jar")} #{_(assembly_dir)}/META-INF/MANIFEST.MF .` 
Dir.chdir present_dir 

Es gibt auch eine Version, dass supports Spring, indem er alle verketten spring.schemas

Verwandte Themen