2016-12-06 21 views
2

私は大きなJavaライブラリを持っており、このライブラリとインターフェイスするいくつかの小さなアプリケーションを開発したいと考えています。ライブラリはJARとしてターゲットデバイスのクラスパス上に存在しますが、可能であればコンパイル時にライブラリ全体(JARまたはソースのいずれか)を表示する必要はありません。 (問題がある場合、JARは非常に大きく、私の主な関心事ではないが、知的財産を保護したい。)関連するクラスと関数の定義ヘッダーをプロジェクトに追加し、コンパイル時にパスをインクルードするように追加すると、実行時に動的リンカーがそのジョブを実行できるようになります。JavaのC++ヘッダーファイルに相当しますか?

Javaでこれを行う方法は?私が持っているアイデアの1つは、プライベートメソッド/メンバーを削除し、関連するクラスのメソッドを削除して、ボディが空であり、同じシグネチャを持つ実際のクラスとメソッドが実行時にロードされるようにすることです。しかし、このアプローチはかなり醜いと思われますが、このプロセスを自動化するためにはいくつかのツールが必要になります。これを行うためのツールはありますか?より良い方法がありますか?

私はそれがthis questionと重複しているとは思わない。この問題のポイントは、不要なクラスを削除することによって、コンパイル時に結果として生じるJARファイルのサイズを最小限に抑えることです。私の指摘は、未使用の定義を削除するのではなく、コンパイル時に完全なライブラリJARを持つ必要性を避けることです。これらは類似していて、ProGuardを使って欲しいものを達成する方法があるかもしれませんが、リンクされた質問ではそれについて論じません。

+2

Javaにはヘッダファイルと同等のものはありません。これは非常に、非常に、非常に良いことです。うん、3つの非常にです。 – Michael

+0

[使用されたクラスのみで最小化されたjarを生成する]の可能な複製(http:// stackoverflow。com/questions/9518400/generate-minimized-jar-only-used-classes) – Michael

+0

まあ、ヘッダーファイルは確かに頭痛になることがあります。しかし、それは私の質問のポイントではありませんでした。コンパイル時に知らなくてはならない実装を、Javaでコンパイル時に知る必要があるライブラリインタフェースからどのように分離するかがポイントでした。 –

答えて

3

あり、Javaでヘッダファイルには、完全に同等ではませんが、実際の実装を持たずに(「契約」の意味で)「ヘッダー」に対してコンパイルするインターフェースを使用して達成することができますするためのインタフェースを作成します

  • 関連するメソッド
  • を持つあなたがのために「ヘッダ」をしたいすべてのクラスは、実際のクラスは別の1
      にそれぞれのインタフェース
    • パックインタフェース1つのJARに、および実装を実装してください
    • (あなたはMavenのようなビルドツールを使用している場合、二つのプロジェクトを使用し、実装プロジェクトは、インタフェース1に依存しましょう)
  • コンパイル時にのみインタフェースJARを提供し、実行時
  • の両方で

もちろん、実際の実装を知っていてインスタンス化できるアーティファクトである必要があります。適切な実装のためにクラスパスを検索するルックアップを使用する必要があります。

+0

さて、良い提案。私はこのようなことを考えていた。私はクラスを変更してJavaインターフェイスを導入する必要はないが、それが助けられないように思えるなら、それはよかっただろう... –

+0

このような巨大な作業の理由は何でしょうか?適切なパッケージで数十万のインターフェースを作るために必要なものをイメージすることができます。何のために? – Vadim

+0

@JanHadáček私が投稿した可能性のある重複した質問の回答は、定型句を必要としないソリューションを提供します。 – Michael

2

最終的なjarが最小限に抑えられているだけで、Apache Mavenを使用している場合は、pom.xmlに依存関係を宣言するときに "提供される"というオプションを使用できます。

<dependency> 
     <groupId>org.bouncycastle</groupId> 
     <artifactId>bcpkix-jdk15on</artifactId> 
     <version>1.48</version> 
     <scope>provided</scope> 
    </dependency> 

これは私のJavaコンパイラはコンパイルにはBouncyCastleライブラリを使用することを意味するが、最終的にはそれが最終的な瓶の中に含まれていません。

は、例えば、私は、この依存関係の宣言を使用します。実行中に提供する必要があります。

+0

ありがとうございます。これは実際に私の問題の一部を解決します。私が@ Jiri Tousekのインターフェースと組み合わせると、それが解決策になるかもしれません。 –

+0

それを忘れる。 は、巨大なJARがローカルマシン上にあり、コンパイル時にクラスパスに入ることを意味します。また、Mavenであり、プロジェクトがEARまたはWAR(つまりJAR)でない限り、 "huge JAR"はどこにも含まれません。それはクラスパスになければなりません。もう一度、それを達成しようとしていますか?あなたの "巨大なJAR"がコンパイルと実行時に違うという意図はありますか?そのような場合でも、「インターフェース」のアイデアは悪いです。 – Vadim

+0

「インターフェイス」テクニックが意味を持つかどうかを調べます。 javax.servlet.apiライブラリがあり、一般的にはインタフェース(または抽象クラス)のみを持ちます。次に、異なるサーブレットコンテナは実装が異なります(WebLogic、WebSphere、TomCat、JBoss ASなど)。したがって、javax.servlet.apiだけを使ってコードを書くことができ、それらのコンテナのどれでも動作します。だから、あなたはあなたの "巨大なJAR"と同様の要件に直面していますか? – Vadim

関連する問題