2011-10-19 20 views
12

से कक्षा को बाहर निकालें मैं एक विरासत जार परियोजना को एसबीटी में परिवर्तित कर रहा हूं और अजीब कारणों से आसानी से हल नहीं कर रहा हूं, यह परियोजना "जावैक्स/सर्वलेट/सर्वलेट.क्लास" के अंदर आता है। तो मुझे पैकेज-बिन द्वारा उत्पन्न जार फ़ाइल से इस वर्ग को किसी भी तरह से बाहर करने की आवश्यकता है। मैं इसे कैसे पूर्ण करूं ?। अधिमानतः मैं वाइल्डकार्ड (यानी जावैक्स का उपयोग करके बाहर करना चाहता हूं। *)।एसबीटी: जार

एसबीटी विधानसभा प्लगइन दिखता है जैसे कि यह विशेषताएं है कि यह कर देगा है, लेकिन मैं चिंतित एसबीटी विधानसभा पर निर्भर इसका मतलब है कि मेरी जार परियोजना एक muliti मॉड्यूल परियोजना (यानी में काम नहीं करेगा अगर मैं के रूप में यह शामिल कर रहा हूँ युद्ध फ़ाइल में निर्भरता के बाद युद्ध परियोजनाओं को असेंबली को पैकेज-बिन के बजाय निर्भर जार परियोजना पर चलाने के लिए कहा जाना चाहिए - लेकिन मुझे यहां गलत समझा जा सकता है)।

उत्तर

13

प्रत्येक कार्य अन्य कार्यों और सेटिंग्स का उपयोग करता है जो इसका उपयोग करता है। Inspecting Settings पर वर्णित इन इनपुट को निर्धारित करने के लिए आप inspect का उपयोग कर सकते हैं और हाल ही में ट्यूटोरियल-शैली blog post by John Cheng पर बता सकते हैं।

इस मामले में, packageBin द्वारा उपयोग किया जाने वाला प्रासंगिक कार्य mappings है। mappings कार्य जार में शामिल करने के लिए फ़ाइलों को एकत्र करता है और उन्हें जार में पथ पर मानचित्रित करता है। कुछ पृष्ठभूमि Mapping Files पर समझाया गया है, लेकिन परिणाम यह है कि mappingsSeq[(File, String)] प्रकार का मान बनाता है। यहां, फ़ाइल सामग्री प्रदान करने वाली इनपुट फ़ाइल है और स्ट्रिंग जार में पथ है।

तो, packageBin कार्य के लिए मैपिंग संशोधित करने के लिए, उन्हें फ़िल्टर डिफ़ॉल्ट मैपिंग से पथ जिसे आप शामिल नहीं करना चाहता:

mappings in (Compile,packageBin) ~= { (ms: Seq[(File, String)]) => 
    ms filter { case (file, toPath) => 
    toPath != "javax/servlet/Servlet.class" 
    } 
} 

mappings in (Compile,packageBin) मुख्य पैकेज कार्य के लिए मैपिंग का चयन करता है (के रूप में परीक्षण स्रोतों या पैकेज एसआरसी कार्य का विरोध किया)।

x ~= f का अर्थ है "एक्स के पिछले मान में फ़ंक्शन f लागू करने के परिणामस्वरूप x सेट करें"। (विवरण के लिए More About Settings देखें।)

फ़िल्टर सभी जोड़ों को छोड़ देता है जहां पथ सर्वलेट वर्ग से मेल खाता है।

+0

यह मेरे अपने और एक शानदार उत्तर से कहीं बेहतर समाधान है क्योंकि यह रास्ते में कुछ मूल एसबीटी अवधारणाओं को स्पष्ट करने में भी कामयाब रहा। –

+0

ध्यान दें कि ~ = 0.13 पेज पर दस्तावेज नहीं है, स्पष्टीकरण 0.12 दस्तावेज़ों में मौजूद है http://www.scala-sbt.org/0.12.4/docs/Getting-Started/More-About-Settings.html –

+0

0.13 के लिए सिंटेक्स : '' मैपिंग्स (संकलन, पैकेजबिन): = { (मैपिंग्स (संकलन, पैकेजबिन))। Value.filter {case (फ़ाइल, toPath) => toPath! = "Javax/servlet/Servlet.class " } }' '' –

2

मैं इस समाधान के साथ आया था, यह एक नई संकलन कार्य जो पिछले संकलन कार्य पर निर्भर करता है परिभाषित करता है (इस प्रकार प्रभावी ढंग मुझे सही में हुक करने के बाद स्रोत संकलित किया गया है की अनुमति देता है और इससे पहले कि यह पैक है)

def mySettings = { 
    // add functionality to the standard compile task 
    inConfig(Compile)(Seq(compile in Compile <<= (target,streams,compile in Compile) map{ 
    (targetDirectory, taskStream, analysis) => 
     import taskStream.log 
     // this runs after compile but before package-bin 
     recursiveListFiles(targetDirectory, ".*javax.*".r) foreach { 
     file => 
      log.warn("deleting matched resource: " + file.getAbsolutePath()) 
      IO.delete(file) 
     } 
     analysis 
    })) ++ 
    Seq(name := "MyProject", version := "1.0", exportJars := true) 
} 

def recursiveListFiles(f: File, r: Regex): Array[File] = { 
    val these = f.listFiles 
    val good = these.filter(f => r.findFirstIn(f.getName).isDefined) 
    good ++ these.filter(_.isDirectory).flatMap(recursiveListFiles(_, r)) 
} 

यह मेरी अपेक्षा से थोड़ी अधिक जटिल है लेकिन यह मुझे पैकेजिंग से पहले सभी प्रकार के संशोधनों को करने की अनुमति देता है (इस मामले में नियमित अभिव्यक्ति से मेल खाने वाली सभी वर्ग फ़ाइलों को हटाने वाले लक्षित फ़ोल्डर को खोजना)। इसके अलावा यह डिफ़ॉल्ट एसबीटी जीवन चक्र के साथ चिपकने का मेरा दूसरा लक्ष्य पूरा कर लिया।