टॉमकट और ग्रहण को एक गर्म वातावरण के रूप में एकीकृत करना


88

मैं एक एकीकृत फैशन में ग्रहण और टॉमकैट को सेटअप करना चाहूंगा, जो कि मेरे जेएसपी और सर्वलेट्स में बदलाव (यदि संभव हो) एक तैनाती की आवश्यकता के बिना immedietely परिलक्षित होते हैं।

ठीक है, यह उन सवालों में से एक है जिनके पूरे इंटरनेट पर बहुत सारे उत्तर हैं, लेकिन वे सभी अलग-अलग लगते हैं। (Sysdeo प्लगइन का उपयोग करें, JBOss प्लगइन का उपयोग करें, एक पुराने ग्रहण के साथ सामान करें, इसके बजाय MyEclipse का उपयोग करें) और मुझे संदर्भित करने के लिए 1 निश्चित संसाधन नहीं मिला। तो मेरे लाभ के लिए, इसे स्थापित करने के लिए सबसे सरल और सबसे अनुशंसित प्रक्रिया क्या है?

यह मानता है कि मेरे पास स्वतंत्र रूप से चलने वाले ग्रहण और टोमैट हैं। मैं वास्तव में यहां निर्देशों का उपयोग करके उन्हें एक गैर-गर्म तैनाती वाले फैशन में एकीकृत करने में कामयाब रहा हूं: http://www.ibm.com/developerworks/opensource/library/os-eclipse-tomcat/index.html

ग्रहण संस्करण संस्करण: ३.४.२ (गेनीमेड) तोमकैट v6.0.20


17
4 साल बाद, मैं इस तथ्य से चकित हूं कि यह अभी भी एक मुद्दा है। चलो, यह बहुत मौलिक है।
कोनराड ग्रास

7 साल बाद (लगभग), मुझे लगता है कि मैंने एक समाधान खोज लिया है: stackoverflow.com/a/37064672/1034436
martian111

जवाबों:


75

दो विकल्प हैं।

सबसे पहले, ग्रहण आपको ऐसा करने देता है, कॉन्फ़िगरेशन के थोड़े बदलाव के साथ (यह विस्तृत पोस्ट भी देखें )

  • सर्वर सूची में टॉमकैट जोड़ें
  • परियोजना को "डायनामिक वेब प्रोजेक्ट" बनाएं (या तो निर्माण विज़ार्ड के माध्यम से या सेटिंग्स में पहलुओं अनुभाग के माध्यम से)
  • टॉमकैट में प्रोजेक्ट जोड़ें, और इसके "परिनियोजन असेंबली" को कॉन्फ़िगर करें
  • विन्यास को खोलने के लिए सूची से डबल क्लिक करें
  • "प्रकाशन" को "कभी भी स्वचालित रूप से प्रकाशित न करें" में बदलें (इसका अर्थ है कि जब आप ctrl + s को मारेंगे तो सर्वर पुनः आरंभ नहीं होगा)
  • डीबग मोड में टॉमकैट शुरू करें

यह अभी भी कोड परिवर्तनों को प्रतिबिंबित करेगा लेकिन सर्वर को पुनरारंभ नहीं करेगा।

दूसरा, मैंने लंबे समय से FileSync प्लगइन का उपयोग किया है :

  • बिन निर्देशक से सभी वर्गों को भेजने के लिए प्लगइन को कॉन्फ़िगर करें WEB-INF/classesअपने टॉमकैट इंस्टॉलेशन (यह तैनाती विधानसभा को कॉन्फ़िगर करने के समान है)
  • अन्य सभी संसाधनों को उनके संबंधित स्थानों पर जाने के लिए कॉन्फ़िगर करें
  • वैकल्पिक रूप से, filesync स्थान सेटिंग्स से सभी पूर्ण पथों को किसी एकल चर में बाह्य करें, और उस चर को ग्रहण में कॉन्फ़िगर करें (इस प्रकार आप फ़ाइलसंकट सेटिंग्स भी कर पाएंगे, यदि सभी सदस्य ग्रहण का उपयोग कर रहे हैं)
  • ग्रहण में सर्वर सूची में टॉमकट जोड़ें, "सर्वर स्थानों का उपयोग करें" विकल्प को कॉन्फ़िगर करें "टॉमकैट इंस्टॉलेशन का उपयोग करें" (सर्वर सूची से टॉमकैट को डबल-क्लिक करने पर स्क्रीन खुलती है)
  • डीबग मोड में टॉमकैट शुरू करें

यह मेरे लिए उस तरह से पूरी तरह से काम करता है। प्रत्येक गैर-संरचनात्मक परिवर्तन को तुरंत दिखाया जाता है, बिना पुनर्वितरण के।

अपडेट:
आप यहां पर गर्म-तैनाती के तरीकों के बारे में अधिक पढ़ सकते हैं ।
मैंने एक प्रोजेक्ट भी बनाया जो सर्वलेट कंटेनर के साथ कार्यक्षेत्र को आसानी से सिंक करता है।


@VladimirTsvetkov नहीं - ये दो अलग-अलग विकल्प हैं
Bozho

मैं आपके पहले दृष्टिकोण की कोशिश कर रहा हूं, लेकिन मैं मावेन ओवरले का उपयोग कर रहा हूं और जब मैं एक ओवरले में एक फाइल को बदलता हूं तो सर्वर अभी भी पुनरारंभ होता है (ओवरले गतिशील वेब परियोजना नहीं है लेकिन गतिशील वेब मॉड्यूल है)। कोई विचार?
हॉफमैन

2
मुझे आभास है कि "प्रकाशन" को "कभी भी स्वचालित रूप से प्रकाशित नहीं" करने से जेएसपी को फिर से लोड / पुनर्नवीनीकरण नहीं किया जाता है जब परिवर्तित किया जाता है। हालांकि डिबग मोड में टॉमकैट शुरू करके क्लास-री-लोडिंग भाग ठीक काम करता है।
yglodt

5
मैं इसे दूसरे तरीके से करता हूं: पहला, स्वचालित रूप से प्रकाशित करने के लिए परिवर्तन; दूसरा, Modulesसर्वर कॉन्फ़िगरेशन में टैब पर क्लिक करें, फिर क्लिक करें edit, अनचेक करें auto deploy enabled, मुझे लगता है कि यह सबसे सरल तरीका है। पुनश्च: आपका पहला तरीका मेरे लिए काम नहीं करता है।
हाईवे

@hiway, सर्वर कॉन्फ़िगरेशन टैब के अंदर यह मॉड्यूल टैब कहां है?
माटूस विस्करी

30

बस ग्रहण को क्लास की फाइल को सीधे TOMCAT / webapps / MyWebApp / WEB_INF / क्लासेस डायरेक्टरी में लिखने दें। फिर, अपाचे-टॉमकैट को कॉन्फ़िगर करें यह जांचने के लिए कि क्या वर्ग फाइलें अपडेट की गई हैं, और यदि उनके पास है तो उन्हें फिर से लोड करें।

जब यह बदलता है, तो आपको एक वर्ग को ऑटो-रीलोड करने के लिए टॉमकैट को कॉन्फ़िगर करना होगा

संपादित करें $TOMCAT/conf/context.xmlऔर सेट करें:

<Context reloadable="true"> 

आपको अपनी webapps/$YourWebApp/web.xmlफ़ाइल को संपादित और पुनः लोड करना पड़ सकता है और इसमें शामिल हैं:

<web-app reloadable="true">

मुझे याद नहीं है कि दोनों परिवर्तनों की आवश्यकता है, लेकिन यह है कि मैंने अपने टोमैट-6.0.18 को ऑटो-रीलोड में कैसे कॉन्फ़िगर किया है।


प्रलेखन के अनुसार, tomcat.apache.org/tomcat-6.0-doc/config/context.html वे Contextserver.xml फ़ाइल में तत्वों को रखने के खिलाफ सलाह देते हैं , लेकिन इसे मॉनिटर / WEB-INF / कक्षाएं / और WEB-INF करना चाहिए / किसी भी परिवर्तन के लिए देय। आपने web-appतत्व के लिए विशेषता के बारे में कहां पढ़ा ?
माइकल

क्षमा करें, अपने उत्तर को थोड़ा गलत करें। संदर्भ। Xml "प्रत्येक वेब अनुप्रयोग के लिए लोड किया जाना चाहिए"।
माइकल

2
आप कैसे कॉन्फ़िगर करते हैं जहां ग्रहण कक्षा-फाइलों को लिखता है?
यगलोद

7

अस्वीकरण : मैं सिर्फ एक खुश ग्राहक हूं, मैं शून्य टर्नअराउंड के लिए काम नहीं करता हूं और मैं किसी भी तरह से उनके साथ संबद्ध नहीं हूं।

JRebel की जाँच करें - यह आपको वेब एप्लिकेशन पुनरारंभ किए बिना कोड करने की अनुमति देता है। यह मूल रूप से आपकी कक्षाओं को साधने और उनके परिवर्तनों को अपनाने के द्वारा काम करता है। यह गर्म तैनाती की तुलना में कई और मामलों को संभालता है , जिनमें शामिल हैं:

  • विधियों को जोड़ना / निकालना
  • कंस्ट्रक्टरों को जोड़ना / हटाना
  • इंटरफेस बदलना
  • कार्यान्वित इंटरफेस को जोड़ना / हटाना

यह वाणिज्यिक है , ( मूल्य निर्धारण विवरण , $ 550 / वर्ष जून 2018 तक), और इसमें थर्ड पार्टी फ्रेमवर्क के लिए बहुत सारे प्लगइन्स शामिल हैं:

  • Guice
  • वसंत
  • स्ट्रट्स 2

आपको नि: शुल्क परीक्षण काफी दर्द रहित रूप से मिलता है - मेरा सुझाव है कि आप इसे एक शॉट दें।


2
Jrebel, जब यह काम करता है, तो यह काम करता है। जब यह नहीं होता है, यह एक बुरा सपना है। मैं एक सप्ताह से अधिक समय तक उनके समर्थन से अपना सिर पीटता रहा हूं और मुझे अभी भी अपने साधारण स्प्रिंग पीवीसी सेटअप में काम करने के लिए नहीं मिल रहा है। वे मेरे बिना मुझे अपना ऐप भेजने में मदद नहीं करेंगे या मेरे ऐप का नरकगृह नहीं। और, आपके मूल्य पुराने हैं - वे अब एक बम चार्ज करते हैं। भगवान का शुक्र है कि मैंने केवल उनके परीक्षण संस्करण का उपयोग किया
happybuddha

वर्तमान कीमत $ 365 / वर्ष / सीट है
जोसेफ लस्ट

और अब इसकी $ 550 / वर्ष / सीट
frewper

3

ग्रहण में अपने कार्यक्षेत्र को बदलकर \ tomcat \ webapps करें क्योंकि यह सिर्फ आपके काम के लिए है, यह ठीक काम करना चाहिए। ग्रहण में आप जो भी बदलाव करते हैं वह उसी निर्देशिका में होता है जहां टॉमकैट तैनात करने के लिए आवेदन करता है


3

सर्वर दृश्य में, एक नया सर्वर बनाएं, सर्वर पर अभी तक कोई संसाधन (परियोजना) न जोड़ें। सर्वर स्थान में सर्वर पर डबल क्लिक करें। "टोमकाट इंस्टॉलेशन का उपयोग करें" चुनें। टॉककैट परिनियोजित निर्देशिका (उदा: c: \ server \ Tomcat 7.0.14 \ webapps) के लिए "पथ को संशोधित करें"। "प्रकाशन अनुभाग" बढ़ाएँ। एक निर्माण घटना के बाद "स्वचालित रूप से प्रकाशित करें" जांचें। सहेजें और बंद करें। ग्रहण मेनू से "प्रोजेक्ट -> स्वचालित रूप से निर्माण करें" जांचें। सर्वर दृश्य से, अपने सर्वर पर राइट क्लिक करें, "जोड़ें और निकालें", आपको प्रोजेक्ट प्रकाशित करें।


2

यदि यह सिर्फ विकास के लिए है तो ग्रहण में एक एकीकृत टोमैट सर्वर का उपयोग क्यों नहीं किया जाता है? आप विंडो-> प्राथमिकताओं के तहत सर्वर कॉन्फ़िगर कर सकते हैं। एक बार यह कॉन्फ़िगर हो जाने पर यदि आपके पास jsp नामक पेज है। तो आप इसे राइट क्लिक कर सकते हैं और सर्वर पर रन का चयन कर सकते हैं। वरीयताओं के तहत-> सामान्य-> वेब ब्राउज़र आप बिल्ट इन ब्राउज़र या किसी बाहरी का उपयोग करने के लिए मौसम चुन सकते हैं। अपने jsp में कुछ बदलाव करें, अपने पेज को ब्राउजर से सेव और रिफ्रेश करें। आपके ब्राउज़र को सहेजने और ताज़ा करने के बाद परिवर्तन स्वचालित रूप से परिलक्षित होंगे।


2

यहाँ मेरे लिए क्या काम करता है:

संदर्भ। इस तरह से:

<Context path="/myapp" docBase="myapp" debug="5"
    reloadable="false" antiResourceLocking="false" antiJARLocking="true">
<!-- this because i´m using Spring 3.1 with Tomcat -->
    <Loader     loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader" />

</Context>

फिर, ग्रहण में सर्वर टैब पर, "मॉड्यूल" टैब पर, मैंने "ऑटो रीलोड" को सभी मॉड्यूलों पर तैनात किया।

ऑटो को प्रकाशित करने के लिए डिफ़ॉल्ट कॉन्फिगर भी करें।

और WTP के साथ मावेन का उपयोग कर रहा है, इसमें src / main / resource की सामग्री को छोड़ना मत भूलना, क्योंकि ग्रहण अंतिम बिल्ड के इस फ़ोल्डर की सामग्री को बाहर करने पर जोर देता है।

केवल इस सब के साथ मुझे पूर्ण (VM) कक्षाएं मिलीं, जो हॉट-फ़ोरम संसाधनों के साथ गर्म-तैनात हैं !!!


1

अपने विकास के माहौल में, बस अपने टॉम्कट सर्वर को इंगित करें कि आप जिस भी डायरेक्टरी में उन्हें विकसित कर रहे हैं, उसमें जेएसपी देखने के लिए। जैसे ही आप फाइल को सेव करेंगे, आप तब बदलाव देख पाएंगे।


1

मैं स्प्रिंग लोडेड JVM एजेंट का उपयोग करके अपने विकास के माहौल पर काम करने में कामयाब रहा हूं । जबकि मैं स्प्रिंग वेब एप्लिकेशन विकसित करता हूं, उस प्रोजेक्ट के विवरण में उल्लेख है कि यह है

JVM पर चलने वाले किसी भी बायोटेक पर प्रयोग करने योग्य

निम्नलिखित सेटअप का उपयोग करते हुए, मैं एक संलग्न टॉमकैट उदाहरण (सामान्य ग्रहण WTP विधि) को स्वचालित रूप से प्रकाशित करने के लिए परिवर्तन प्राप्त करने में सक्षम था। मैं स्प्रिंग टूल सूट का उपयोग कर रहा हूं 3.7.3 ग्रहण मंगल पर आधारित है ।.2 (4.5.2)।

  1. उनके Github प्रोजेक्ट से लोड किए गए स्प्रिंग का नवीनतम रिलीज़ JAR डाउनलोड करें । यह स्प्रिंगलोडेड-1.2.5.RELEASE.jar के साथ परीक्षण किया गया है।
  2. सामान्य रूप में ग्रहण में एक टॉमकैट सर्वर सेट करें (टॉमकैट 8.0.30 के साथ परीक्षण किया गया)
  3. एक्लिप्स में टॉमकैट सर्वर का कॉन्फ़िगरेशन पृष्ठ खोलें ("सर्वर" टैब के भीतर सर्वर उदाहरण पर डबल-क्लिक करें)।
  4. "सर्वर विकल्प" अनुभाग में, "मॉड्यूल ऑटो डिफ़ॉल्ट रूप से पुनः लोड करें" को अनचेक करें।
    • नोट: यदि आपके पास वेब मॉड्यूल पहले से ही सर्वर में जोड़े गए हैं, तो आपको "मॉड्यूल" टैब (कॉन्फ़िगरेशन पृष्ठ विंडो के नीचे) के माध्यम से उन पर व्यक्तिगत रूप से "ऑटो रीलोड" को अक्षम करना पड़ सकता है।
  5. "सामान्य जानकारी" अनुभाग में, "ओपन लॉन्च कॉन्फ़िगरेशन" पर क्लिक करें
    • "तर्क" टैब में, "VM तर्क" के अंत में निम्नलिखित जोड़ें: -javaagent:/path/to/downloaded/springloaded-1.2.5.RELEASE.jar -noverify
    • प्रोजेक्ट की .classफ़ाइलों के अलावा JAR को देखने के लिए सक्षम करने के लिए , इस मुद्दे की टिप्पणियों के-Dspringloaded=watchJars= अनुसार VM तर्क को कॉन्फ़िगर करें ।

सर्वर शुरू करें और हमेशा की तरह डायनामिक वेब एप्लिकेशन प्रोजेक्ट प्रकाशित करें। फिर से, मैं स्प्रिंग वेब एप्लिकेशन के साथ इसका परीक्षण करने में सक्षम था। उदाहरण के लिए, @Controller क्लासेस में मोडिफाई कोड, जोड़ / घटाना, आदि को फाइल को सेव करने के बाद तुरंत लागू किया गया और एक्लिप्स ने बिल्ड क्लास को बदला और प्रकाशित किया। अंत में, स्प्रिंग लोडेड प्रोजेक्ट के अक्सर पूछे जाने वाले प्रश्न अनुभाग में कुछ मामलों का उल्लेख किया गया है जहां चीजें फिर से लोड नहीं होंगी, इसलिए उन सर्वर / एप्लिकेशन को पुनरारंभ करने की आवश्यकता होगी। लेकिन वे अपवाद अक्सर कम होते हैं।

एक और ध्यान दें: यह एम्बेडेड Pivotal tc सर्वर या VMware vFabric tc सर्वर के साथ काम नहीं करता है जो STS के साथ आता है। उन सर्वरों के लिए, "सक्षम जावा एजेंट-आधारित रीलोडिंग (प्रायोगिक)" विकल्प है, लेकिन वह स्प्रिंग लोड किए गए 1.2.0 पुराने रिलीज का उपयोग करता है, जो मेरे लिए काम नहीं करता था।


ऐसा लगता है कि आपको आवेदन के Springबारे में जानकारी अवश्य लेनी चाहिए Non Spring
टैंगू

हालांकि आपको टॉमकैट के लिए स्प्रिंगवॉल्ड जेएआर को कॉन्फ़िगर करने की आवश्यकता है, चल रहे एप्लिकेशनों को स्वयं स्प्रिंग एप्लिकेशन (न ही कोई स्प्रिंग जार शामिल करने की आवश्यकता है) की आवश्यकता है। मैंने इसे एक सरल, सिंगल हैलोवर्ल्ड सर्वलेट के साथ सफलतापूर्वक परीक्षण किया।
Martian111

0

क्या आप विकास के उद्देश्यों के लिए जेट्टी का उपयोग करने के लिए खुले हैं?

यदि हां, तो मावेन के साथ उपयोग करना बहुत आसान है - बस चलाएं mvn jetty:run


0

यह सबसे अच्छा तरीका नहीं हो सकता है, लेकिन यह मेरे लिए काम करता है।

  • $ बिल्ला / conf / कैटालिना / स्थानीय होस्ट / .xml
  • $ ContextPath / webapp / वेब / वेब-INF / lib / *। जार
  • $ ContextPath / webapp / वेब /
  • $ EclispeWorkbench / परियोजना सर्वलेट / src /
  • $ eclispeWorkbench / project-servlet / servlet.jardesc ($ $ $ $ $ $ $ $ $ $ $
  • $ EclipseWorkbench / परियोजना jsp /

मैं अपने jsp प्रोजेक्ट से $ रेफरेंसपैथ में बदलाव को सिंक करने के लिए rsync कमांड का उपयोग करता हूं।

टॉमकैट के लिए एक्लिप्स में दूरस्थ डिबगिंग का उपयोग करें जो कोड के सीमित गर्म-स्वैपिंग की अनुमति देगा। यदि आप स्थैतिक फ़ील्ड बदलते हैं या विधियाँ जोड़ते हैं, तो आपको जार को निर्यात करने और संदर्भ को पुनरारंभ करने की आवश्यकता होगी।


0

क्या हम नीचे दिए गए विकल्प का उपयोग कर सकते हैं? ग्रहण में सर्वर पर डबल क्लिक करें -> सर्वर स्थान -> टॉमकट इंस्टॉलेशन का उपयोग करें। यह टॉमकैट इंस्टॉलेशन को नियंत्रित करता है। आपको जावा कक्षाओं में परिवर्तन के लिए सर्वर को पुनरारंभ करने की आवश्यकता नहीं है।


0

मुझे एक सरल तरीका मिल गया है: प्रतीकात्मक लिंक का उपयोग: मुझे लगता है कि यह सबसे तेज़ तरीका है क्योंकि सभी में कोई सिंक्रनाइज़ेशन नहीं है: टॉमकैट निर्देशिका और आपकी परियोजना निर्देशिका हर समय एक ही निर्देशिका होगी।

टॉमकैट समय-समय पर परिवर्तनों का पता लगाएगा और आपके आवेदन को फिर से तैयार करेगा।

आपके एप्लिकेशन को डीबग करने का एक तरीका भी है, इसलिए मुझे विनम्रतापूर्वक लगता है कि यह एक अच्छा समाधान है।

मैंने अपने समाधान का दस्तावेज यहां दिया है , किसी की दिलचस्पी के लिए।


क्या मुझे पता है कि स्थानीय जावा एप्लिकेशन का उपयोग करने की आवश्यकता क्यों है क्योंकि यह लोकलहोस्ट का उपयोग कर रहा है जिसका अर्थ है कि मैं अपने स्वयं के स्थानीय मशीन का उपयोग कर डिबग कर रहा हूं
करेन गोह

0

मामले में, आप जल्दी में हैं:

  1. ग्रहण में टॉमकैट (अन्य कंटेनर) में "कभी भी स्वचालित रूप से प्रकाशित न करें" जांचें।
  2. डीबग मोड में टॉमकैट (अन्य कंटेनर) शुरू करें।

देखा! :)


0

ग्रहण में, शीर्ष मेनू में प्रोजेक्ट पर क्लिक करें और सुनिश्चित करें कि "स्वचालित रूप से निर्माण करें" चुना गया है। इससे मेरी समस्या ठीक हो गई। मैं अपने कार्यक्षेत्र मेटाडेटा का उपयोग करके टॉमकैट के साथ ग्रहण चला रहा था। मैं एक गतिशील वेब मॉड्यूल परियोजना में मावेन भी चला रहा था। सत्यापित करने के लिए, अपने आवेदन को टॉमकैट में जोड़ें। ग्रहण के भीतर से टॉमकैट शुरू करें। सुनिश्चित करें कि आपका आवेदन तैनात और चल रहा है। ग्रहण में कंसोल टैब खोलें। अपने आवेदन में बदलाव करें। कुछ सेकंड के बाद, आपको अपने बदलाव को स्वचालित रूप से निर्मित और टॉमकैट पर तैनात होते हुए देखना चाहिए।


-2

सबसे सरल, तेज: जब आप निर्माण करते हैं तो WAR फ़ाइल बनाने के लिए ग्रहण सेट करें; एक पोस्ट-बिल्ड स्टेप के रूप में, उस WAR फ़ाइल को अपने tomcat webapps डायरेक्टरी में कॉपी करें। टॉमकैट परिवर्तन को पहचान लेगा और आवश्यक तैनाती के साथ साइट को ताज़ा नहीं करेगा। ध्यान दें कि यह सही नहीं है; उस वेबएप का उपयोग करने वाले उपयोगकर्ताओं के पास इष्टतम अनुभव से कम हो सकता है, क्योंकि टॉमकैट वेबएप को "उनके तहत" फिर से शुरू करता है; लेकिन यह आपके अनुरोध पर फिट बैठता है।


1
ठीक है ... मुझे लगता है कि मैंने अपने इरादे स्पष्ट नहीं किए। मैं वास्तव में कुछ उपयोगकर्ताओं के लिए ऐप को तैनात करने में दिलचस्पी नहीं रखता हूं, लेकिन मैं अपनी रोजमर्रा की विकास जरूरतों के लिए और बदलाव के फीडबैक चक्र को छोटा करने के लिए एक टॉमकैट चलाने की कोशिश कर रहा हूं -> (परिणाम देखें) बदलाव) -> तैनाती -> (परिणाम देखें)
udit
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.