maven-shard-plugin使用体験
7985 ワード
0.
maven管理項目を使うと便利ですが、依存が多くなるにつれて、ますます面倒になります.
一番頭が痛いのは衝突に依存して最終的に使う方が解決できますが、sdkの提供側としてはもっと面倒です.うまくいかないと使用者dissになります.
このような問題を解決するのに非常に適している不思議なmavenプラグイン、Maven-shard-pluginが最近発見されました.
1.maven-shard-pluginを使用する
直接的に前の例のpom:
簡単にメインクラスを書いて、カバンを作ってみます.
実行してみます.
2.maven-shard-pluginの文字列に対する処理
コード
どうすればいいですか?relocationのpatternをもっと正確に制限する必要があるようです.例えば
もう一度試してみます.問題は確かに解決されました.ただし、コードが
私たちはmaven-shard-pluginのソースコードを見てみたいです.
全体としてはasmを使うことです.関連する
3.その他の資料 Apache Maven Shade Plugin
maven管理項目を使うと便利ですが、依存が多くなるにつれて、ますます面倒になります.
一番頭が痛いのは衝突に依存して最終的に使う方が解決できますが、sdkの提供側としてはもっと面倒です.うまくいかないと使用者dissになります.
このような問題を解決するのに非常に適している不思議なmavenプラグイン、Maven-shard-pluginが最近発見されました.
1.maven-shard-pluginを使用する
直接的に前の例のpom:
4.0.0
scyuan.maven
shade-example
1.0-SNAPSHOT
shade-example
UTF-8
redis.clients
jedis
2.8.0
junit
junit
4.11
test
org.apache.maven.plugins
maven-shade-plugin
3.1.1
redis.clients:jedis
org.apache.commons:commons-pool2
*:*
META-INF/*.SF
META-INF/*.DSA
META-INF/*.RSA
redis
scyuan.maven.shaded.redis
org.apache.commons
scyuan.maven.shaded.org.apache.commons
package
shade
この例では、悪名高いjedisをjarパケットに打ち込み、パケット名プレフィックスをscyuan.maven.shaded.redis
に変更すると、sdkの使用者は、明示的に2.2.0バージョンのjedisに依存してもsdkに壊滅的な影響を与えることはない.簡単にメインクラスを書いて、カバンを作ってみます.
package scyuan.maven;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class App {
public static void main(String[] args) {
String key = "hello";
String value = "redis";
JedisPoolConfig config = new JedisPoolConfig();
JedisPool jedisPool = new JedisPool(config, "127.0.0.1", 6379);
try (Jedis jedis = jedisPool.getResource()) {
jedis.set(key, value);
System.out.println(jedis.get(key));
} catch (Exception e) {
System.out.println(e.toString());
}
jedisPool.close();
}
}
作ったshade-example-1.0-SNAPSHOT.jar
のカバンを解凍してみます.➜ target tree -L 5 shade-example-1.0-SNAPSHOT
shade-example-1.0-SNAPSHOT
├── META-INF
│ ├── LICENSE.txt
│ ├── MANIFEST.MF
│ ├── NOTICE.txt
│ └── maven
│ ├── org.apache.commons
│ │ └── commons-pool2
│ │ ├── pom.properties
│ │ └── pom.xml
│ ├── redis.clients
│ │ └── jedis
│ │ ├── pom.properties
│ │ └── pom.xml
│ └── scyuan.maven
│ └── shade-example
│ ├── pom.properties
│ └── pom.xml
└── scyuan
└── maven
├── App.class
└── shaded
├── org
│ └── apache
└── redis
└── clients
15 directories, 10 files
jedis
およびcommons-pool2
は、私たちの意思に従って対応する位置に現れた.実行してみます.
➜ target java -cp shade-example-1.0-SNAPSHOT.jar:jedis-2.2.0.jar:commons-pool-1.6.jar scyuan.maven.App
scyuan.maven.shaded.redis
出力が予想に合わない以外は正常です.2.maven-shard-pluginの文字列に対する処理
コード
String value = "redis";
の文字列redis
もscyuan.maven.shaded.redis
に置き換えられているように見える.どうすればいいですか?relocationのpatternをもっと正確に制限する必要があるようです.例えば
redis.clients
.もう一度試してみます.問題は確かに解決されました.ただし、コードが
String value = "redis.clients";
となると、前の問題が繰り返されますので、これは注意事項です.私たちはmaven-shard-pluginのソースコードを見てみたいです.
全体としてはasmを使うことです.関連する
RelocatorRemapper
を見つけました.// org/apache/maven/plugins/shade/DefaultShader.java#L564
static class RelocatorRemapper
extends Remapper
{
private final Pattern classPattern = Pattern.compile( "(\\[*)?L(.+);" );
List relocators;
RelocatorRemapper( List relocators )
{
this.relocators = relocators;
}
public boolean hasRelocators()
{
return !relocators.isEmpty();
}
public Object mapValue( Object object )
{
if ( object instanceof String )
{
String name = (String) object;
String value = name;
String prefix = "";
String suffix = "";
Matcher m = classPattern.matcher( name );
if ( m.matches() )
{
prefix = m.group( 1 ) + "L";
suffix = ";";
name = m.group( 2 );
}
for ( Relocator r : relocators )
{
if ( r.canRelocateClass( name ) )
{
value = prefix + r.relocateClass( name ) + suffix;
break;
}
else if ( r.canRelocatePath( name ) )
{
value = prefix + r.relocatePath( name ) + suffix;
break;
}
}
return value;
}
return super.mapValue( object );
}
public String map( String name )
{
String value = name;
String prefix = "";
String suffix = "";
Matcher m = classPattern.matcher( name );
if ( m.matches() )
{
prefix = m.group( 1 ) + "L";
suffix = ";";
name = m.group( 2 );
}
for ( Relocator r : relocators )
{
if ( r.canRelocatePath( name ) )
{
value = prefix + r.relocatePath( name ) + suffix;
break;
}
}
return value;
}
}
mapValue
の方法は、ハードコードのクラス名など、String
を特殊処理する必要があります.3.その他の資料