2010-12-08 10 views
7

APIパッケージのみにアクセスできるjarファイルが必要です。他のすべてのパッケージ(実装を含む)は、別のjar(他のクラスでも)からアクセスできません。Java:jarファイル内に1つのパッケージのみを公開する

可能ですか?

はいの場合はどうですか?

+0

通常、jarは 'jar'コマンドでビルドされます。 Ant、Maven、およびその他のビルドツールは、これを単純に難読化しています。 –

+1

ビルドツールを気にする必要はありません。 – glmxndr

+1

アクセス制御はJavaでこのようには動作しません... – Nate

答えて

3

現在、Java 8(2012?)の予定はJSR 294です。このJSRは、より良いモジュール化言語構造をJavaに導入します。

今日、実装は複数のパッケージに分割できます。そのような実装のサブパートは、周囲のソフトウェア環境よりもより密接に結合される必要があります。今日、設計者は、実装の他のサブパートが必要とするプログラムの要素を公に宣言することにより、それらがグローバルにアクセス可能になり、明らかに最適ではありません。

また、実装全体を1つのパッケージに配置することもできます。これは上記の問題を解決しますが、扱いにくく、すべてのサブパーツのすべての内部を互いに公開します。

想定される言語の変更により、これらの問題が解決されます。特に、モジュールの新しい概念(スーパーパッケージ)を、既存の公開アクセス制御が言語レベルのモジュール内でのみ適用される言語レベルで導入し、モジュールの外部からのAPIへのアクセスがAPIのモジュールに限定されることを期待しています明示的にエクスポートします。

私は専門家グループがまだこのコンセプトの詳細について議論していると思います。言い換えれば

superpackage com.myorg.myApp.model 
{ 
    member package com.myorg.myApp.model.swing; 

    member package com.myorg.myApp.model.html; 

    export com.myorg.myApp.model.swing.SEmployee; 
    export com.myorg.myApp.model.swing.SDepartment; 

    export package com.myorg.myApp.model.html; 
} 

、与えられた「superpackage」のためにあなたは、何で、エクスポートされない視界から独立して定義することができます。しかし、私はあなたが行うことができるかもしれない一つのことは、この(:Super Packages in Java 7.0ソース)であると考えていpublicのようなキーワード

+0

ここに、Mark Reinholdのブログへのリンクがあります。これは、Javaの将来に関する最も権威のあるソースであるように思われます。http://blogs.sun.com/mr/entry/plan_b_details –

+0

JSRは非アクティブとマークされ、最後のアクティビティは2007年には本当に起こりそうですか? – bacar

+0

Mark Reinholdのブログへのリンクがなくなっているようですが、ここに更新されたカップルがあります:http://mreinhold.org/blog/module-system-requirements、http://mreinhold.org/blog/plan-b – bacar

1

「通常の」Javaアプリケーションでは不可能です。 OSGi環境では、バンドル(わずかに変更されたjarファイル)から他のバンドルに公開されるパッケージと、プライベート(バンドル外には表示されないパッケージ)を定義します。

0

APIクラスと、APIクラスに応じて実装された分離されたjarを作成するだけではどうでしょうか。これにより、実装を配布することなくAPIクラスを配布することができます。

KR。

+0

これは今行っていることです。可能であれば、単一の瓶に入れようとするだけです。 – glmxndr

2

あなたがOSGIを使っていない限り、これはJava 6では実際には不可能です。 私が通常クラスを非表示にしてしまうのは、パッケージフレンドリーなクラスを実装に使うことです。しかし、実装クラスが別のパッケージに存在する場合は、いくつかのクラスを公開する必要があります。

サンプル:あなたはそれが公共のクラス修飾子です取り外し可能性があり、それができなくなります同じパッケージ内ServiceImpl命ならば、それは今の実装

だとして

package com.example;

public class Service { }は、APIクラスはServiceImplを使用していますと仮定パッケージ外でアクセス可能...

別パッケージ(あなたの場合)に住んでいる場合は、公開する必要があります:

package com.example.impl;

public class ServiceImpl { }

が、すべての実装の詳細(それは使用しています関連するクラス)同じパッケージから公開する必要はありません!

+0

「あなた」に資本「Y」を入れた理由は何ですか?とにかくニースの答え。 :) – glmxndr

+1

@サタンタンテ:あなたは明らかに神です。 '' –

+0

@サブテンテ私は学校でそのように考えられていた - ちょうど礼儀正しいと思っていた:) – kares

0

私はあなたがそれをしたい理由を見ることができます。誰かの図書館を利用しようとすると、いつも困っています。私はどこから始めるべきか分からない非常に多くのクラスがあります。

ほとんどのライブラリから見る限り、無関係のクラスを隠そうとするライブラリはありません。これは確固たる証拠ではありませんが、それを行う方法がないことを意味するはずです。通常、彼らはapiと実装を別々のjarファイルにまとめます。

OSGiフレームワークでアプリケーションを実行している場合、OSGiフレームに必要なAPIクラスのみが表示されるようにjarファイルをバンドルすることは可能です。しかし、OSGiを使うのはちょっとした作業かもしれません。

0

ビルダーツールの環境設定に必要なコンポーネントをjarにするために、ant-taskまたはmaven-jar-pluginの設定を追加できます。

4

使用しないクラスがある場合は、それらを「internal」という名前のサブパッケージに入れます。これは他の人がクラスを使用するのを妨げるものではありませんが、そうしないと強く示しています。

例:

my.library.Stuff 
my.library.StuffFactory 
my.library.internal.StuffImpl 
my.library.internal.MoreStuff 
my.library.internal.xml.DataStuff 

これは、実際の解決策はありませんが、私はそれのベストプラクティスを検討します。

0

もう1つの解決策は、デフォルトのアクセス修飾子を実装クラスに設定し、それらをinterfacesと同じパッケージに入れることです。その少し汚い方法ですが。

関連する問題