Java: выставить только один пакет в JAR-файл - PullRequest
7 голосов
/ 08 декабря 2010

Я хотел бы иметь файл jar, в котором доступен только пакет API. Все остальные пакеты (содержащие реализации) не будут доступны ни для другого jar (ни для какого-либо другого класса).

Возможно ли это?

Если да, то как?

Ответы [ 8 ]

4 голосов
/ 08 декабря 2010

Если у вас есть классы, которые не должны использоваться, поместите их в подпакет с именем «internal».Хотя это не мешает другим использовать классы, это явный признак того, что им не следует.

Пример:

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

Хотя это не является реальным решением, я бы его рассмотреллучшая практика.

3 голосов
/ 08 декабря 2010

В настоящее время запланировано на Java 8 (2012?) Значение JSR 294 . Этот JSR вводит лучшие языковые конструкции модуляризации в Java.

Сегодня реализация может быть разделена на несколько пакетов. Подразделения такой реализации должны быть более тесно связаны друг с другом, чем с окружающей программной средой. Сегодня дизайнеры вынуждены объявлять элементы программы, которые необходимы другим частям реализации, общедоступными, что делает их общедоступными, что явно неоптимально.

Альтернативно, вся реализация может быть помещена в один пакет. Это решает проблему выше, но громоздко, и выставляет все внутренние части всех частей друг другу.

Предусмотренные языковые изменения позволят решить эти проблемы. В частности, мы ожидаем ввести новое понятие модулей ( superpackages ) на уровне языка, где существующее управление общедоступным доступом будет применяться только внутри модуля языкового уровня, а доступ к API извне модуля будет быть ограниченным API-интерфейсом, который модуль явно экспортирует.

Теперь я считаю, что группа экспертов все еще обсуждает детали этой концепции. Но я верю, что вы могли бы сделать следующее: (источник: Супер-пакеты в Java 7.0 ):

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;
}

Другими словами, для данного «суперпакета» вы можете определить, что экспортируется, а что нет, независимо от ключевых слов видимости, таких как public.

2 голосов
/ 08 декабря 2010

это на самом деле невозможно в Java 6, если вы не используете OSGI, что, я полагаю, не так.что я обычно делаю, чтобы скрыть классы, это использовать дружественные к пакету классы для реализаций, но вам все равно может понадобиться предоставить некоторые классы, если ваши классы реализации действительно живут в отдельном пакете.

sample:

package com.example;

public class Service { } предположим, что класс API использует ServiceImpl в качестве своей реализации

теперь, если ServiceImpl живет в том же пакете, вы можете удалить его общедоступныммодификатор класса, и он не будет доступен вне пакета ...

если он находится в другом пакете (ваш случай), он должен быть общедоступным:

package com.example.impl;

public class ServiceImpl { }

но все детали реализации (связанные с ним классы) из одного и того же пакета не должны быть общедоступными!

1 голос
/ 08 декабря 2010

В «нормальном» Java-приложении это невозможно.Хотя в среде OSGi вы определяете, какие пакеты предоставляются вашим пакетом (слегка измененный jar-файл) другим пакетам, а какие являются частными (не видны за пределами вашего пакета).

0 голосов
/ 09 декабря 2010

Другое решение - установить модификатор доступа по умолчанию в классах реализации и поместить их в тот же пакет, что и интерфейсы. Хотя это немного грязно.

0 голосов
/ 08 декабря 2010

Вы можете добавить конфигурацию ant-task или maven-jar-plugin для jar компонентов, которые вам нужны с учетом предпочтений вашего инструмента разработки.

0 голосов
/ 08 декабря 2010

Я вижу причину, почему вы хотите это сделать.Меня всегда беспокоило, когда я пытаюсь использовать чью-то библиотеку.Существует так много классов, с которых я не знаю, с чего начать.

Насколько я вижу из большинства библиотек, нет такой библиотеки, которая пыталась бы скрыть несвязанные классы.Хотя это не является убедительным доказательством, это должно означать, что нет никакого способа сделать это.Обычно они объединяют api и реализацию в отдельные файлы jar.

Однако, если вы запускаете свое приложение через каркас OSGi, вы можете связать файл jar таким образом, чтобы кадр OSGi мог видеть толькоКлассы API, которые вы хотите.Но использование OSGi может быть немного трудоемким.

0 голосов
/ 08 декабря 2010

Почему бы просто не создать банку с классами API и отдельную банку с реализациями, зависящими от API.Таким образом, вы можете распространять свои классы API, не распространяя свою реализацию.

KR.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...