Bağımlılıkların gölgelenmesi , kendi kodunuzun yanında topladığınız özel bir kopya oluşturmak için bağımlılıkları dahil etme ve yeniden adlandırma işlemidir (bu nedenle sınıfları ve etkilenen sınıfları ve kaynakları yeniden yerleştirme) .
Konsept genellikle über kavanozlarla (aka yağ kavanozları ) ilişkilendirilir.
Bu terimle ilgili bazı karışıklıklar var , çünkü tek bir ad altında 2 şeyi yapan maven gölge eklentisi :
Bu eklenti, artefaktı, bağımlılıkları da dahil olmak üzere bir uber kavanoza koyma ve bazı bağımlılıkların paketlerini gölgelendirme - yani yeniden adlandırma - kabiliyeti sağlar .
Böylece gölgelendirme kısmı aslında isteğe bağlıdır: Eklenti, kavanoza (yağ kavanozu) bağımlılıkları dahil etmeyi ve isteğe bağlı olarak (gölge) bağımlılıkları yeniden adlandırmayı sağlar .
Başka bir kaynak eklemek :
Bir kütüphaneyi gölgelendirmek için, söz konusu kütüphanenin içerik dosyalarını almak, kendi kavanozunuza koymak ve paketini değiştirmek . Bu, farklı bir pakete yerleştirmeden, kendi kütüphanenizdeki kitaplık dosyalarını yanınızda taşıyarak paketlemekten farklıdır.
Teknik olarak konuşursak, bağımlılıklar gölgelendirilir. Ancak, gölgeli bir şişeli-gölgeli bağımlılıklara "gölgeli kavanoz" olarak atıfta bulunmak yaygındır ve bu kavanoz başka bir sistem için bir müşteri ise, "gölgeli müşteri" olarak adlandırılabilir.
İşte sorunuza bağladığınız HBase için Jira sayısının başlığı :
Gölgeli bağımlılıkları olan bir istemci eserini yayınlayın
Yani bu yazıda, 2 kavramı, onları birbirine karıştırmadan sunmaya çalışıyorum.
İyi
Uber-jar'lar genellikle bir uygulamayı tek bir dosya olarak göndermek için kullanılır (dağıtılmasını ve çalıştırılmasını kolaylaştırır). Diğer uygulamaların (bu kitaplıkların farklı sürümlerini kullanabilecekleri) kullandıkları çatışmaları önlemek için, kitaplıkların bazılarının (veya hepsinin) gölgeli olmaları ile birlikte gölgelendirilmesi için de kullanılabilirler.
Über kavanozlarını yapmanın birkaç yolu var, ancak sınıf yer değiştirme özelliği maven-shade-plugin
ile bir adım daha ileri gidiyor :
Uber JAR, başka bir projenin bağımlılığı olarak tekrar kullanılırsa, doğrudan nesnenin JAR'daki bağımlılık sınıflarından doğrudan dahil edilmesi, sınıf yolundaki yinelenen sınıflar nedeniyle sınıf yükleme çatışmalarına neden olabilir. Bu konuyu ele almak için, bayt kodlarının özel bir kopyasını oluşturmak için gölgeli yapıya dahil edilen sınıflar yerleştirilebilir.
(Tarihsel not: Jar Jar Links , bu yer değiştirme özelliğini daha önce sundu)
Bu sayede, API'nizdeki kütüphanelerden sınıfları göstermediğiniz sürece, kütüphane bağımlılıklarınızı bir uygulama detayı haline getirebilirsiniz .
Diyelim ki bir projem var, DecayingSyncQuantanizer
sınıf sağlayan ve Apache commons- rng'ye bağlı olan ACME Quantanizer ™ (tabii ki uygun bir şekilde quantanlaştırmak için XorShift1024Star
).
Bir uber jar üretmek için shade maven eklentisini kullanırsam ve içeri bakarsam, şu sınıf dosyalarını görürüm:
com/acme/DecayingSyncQuantanizer.class
org/apache/commons/rng/RandomProviderState.class
org/apache/commons/rng/RestorableUniformRandomProvider.class
...
org/apache/commons/rng/core/source64/XorShift1024Star.class
org/apache/commons/rng/core/util/NumberFactory.class
Şimdi sınıf değiştirme özelliğini kullanırsam:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
<relocation>
<pattern>org.apache.commons</pattern>
<shadedPattern>com.acme.shaded.apachecommons</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
Uber-jar içeriği şöyle görünür:
com/acme/DecayingSyncQuantanizer.class
com/acme/shaded/apachecommons/rng/RandomProviderState.class
com/acme/shaded/apachecommons/rng/RestorableUniformRandomProvider.class
...
com/acme/shaded/apachecommons/rng/core/source64/XorShift1024Star.class
com/acme/shaded/apachecommons/rng/core/util/NumberFactory.class
Sadece dosyaları yeniden adlandırmakla kalmaz, yeniden yerleştirilmiş sınıflara referans veren bytecode yazar (yani, kendi sınıflarım ve commons-rng sınıflarım hepsi dönüştürülür).
Ek olarak, Shade eklentisi ayrıca dependency-reduced-pom.xml
gölgeli bağımlılıkların <dependencies>
bölümden uzaklaştırıldığı yeni bir POM ( ) üretecektir . Bu, gölgeli kavanozun başka bir projeye bağımlılık olarak kullanılmasına yardımcı olur. Böylece, bu kavanozun yerine bir tane veya her ikisini de (gölgeli kavanoz için bir niteleyici kullanarak) yayınlayabilirsiniz .
Yani bu çok yararlı olabilir ...
Kötü
... ama aynı zamanda bir takım sorunları da beraberinde getiriyor. Tüm bağımlılıkların kavanoz içindeki tek bir "ad alanı" nda toplanması karışıklığa neden olabilir ve gölgelendirme ve kaynaklarla uğraşmayı gerektirir.
Örneğin: sınıf veya paket adlarını içeren kaynak dosyalarıyla nasıl başa çıkılır? Tüm altında yaşayan servis sağlayıcı tanımlayıcıları gibi kaynak dosyalar META-INF/services
?
Gölge eklentisi, bu konuda yardımcı olabilecek kaynak transformatörleri sunar :
Çeşitli eserlerdeki sınıfları / kaynakları tek bir JAR'da bir araya getirmek, üst üste binme olmadığı sürece dümdüz ileridir. Aksi takdirde, birkaç JAR'dan kaynakları birleştirmek için bir tür mantık gerekir. Kaynak transformatörleri burada devreye giriyor.
Ancak yine de dağınıktır ve sorunların önceden tahmin edilmesi neredeyse imkansızdır (sorunları sıklıkla üretimdeki zor yoldan keşfedersiniz). Neden yağ kavanozlarını bıraktığımızı görün .
Sonuçta, bağımsız bir uygulama / hizmet olarak yağ kavanozunu yerleştirmek hala çok yaygındır, sadece gotcha'ların farkında olmanız ve bazılarının gölgelendirme veya başka hilelerden haberdar olmanız gerekir .
Çirkin
Çok daha zor konular var (hata ayıklama, test edilebilirlik, OSGi ve egzotik sınıf yükleyicileriyle uyumluluk ...).
Fakat daha önemlisi, bir kütüphane ürettiğinizde, kontrol edebileceğinizi düşündüğünüz çeşitli konular şimdi daha da karmaşık bir hale geliyor, çünkü kavanozunuz birçok farklı bağlamda kullanılacak (bağımsız bir uygulama / hizmet olarak uyguladığınız yağ kavanozunun aksine) kontrollü bir ortamda).
Örneğin, ElasticSearch, sevk ettikleri kavanozlardaki bazı bağımlılıkları gölgelemek için kullanılır, ancak bunu yapmayı bırakmaya karar verdiler :
Versiyon 2.0'dan önce, Elasticsearch, aynı eserde gölgeli ve paketlenmiş bazı (hepsi değil) ortak bağımlılıklara sahip bir JAR olarak sağlandı. Bu, Guava, Joda, Jackson, vb. Modüllerin sürüm çatışmalarını önlemek için Elasticsearch'ü kendi uygulamalarına yerleştiren Java kullanıcılarının, elbette, yine de çatışmalara neden olabilecek, Lucene gibi diğer gölgesiz bağımlılıkların bir listesi vardı.
Ne yazık ki, gölgelendirme, bazı insanlar için problem yaratırken bazılarına problem çözen karmaşık ve hataya açık bir süreçtir. Gölgeleme, geliştiricilerin ve eklenti yazarlarının kodları doğru bir şekilde yazmasını ve hata ayıklamasını sağlar çünkü paketler oluşturma sırasında yeniden adlandırılır. Sonunda, Elasticsearch'ü gölgesiz olarak test eder, sonra gölgeli kavanozu gönderirdik ve test etmediğimiz hiçbir şeyi göndermeyi sevmiyoruz.
Elasticsearch'ü 2,0 yaşından itibaren gölgelendirmeden göndermeye karar verdik.
Lütfen onların da gölgeli kavanozlara değil gölgeli bağımlılıklara atıfta bulunduklarına dikkat edin.