Можно ли создать псевдоним для пакета?

Можно ли сделать так, чтобы пакет com.example.lib был видим и мог импортироваться под именем ru.example.*?
  • 6 мая 2026 г. 5:00
Ответы на вопрос 1
Короткий ответ: нет — в Java (и в JVM в целом) нет механизма «псевдонима пакета», который позволил бы одним махом сказать «com.example.lib теперь доступен как ru.example.*» на уровне языка/класслоадера.

Варианты достижения похожего результата

1) Переназначение пакетов на этапе сборки (рекоммендовано в большинстве случаев)
- Инструменты: Maven Shade (relocation), Gradle Shadow, JarJar. Они переписывают имена пакетов в .class-файлах и создают JAR, в котором com.example.lib физически переименован в ru.example.
- Плюсы: прозрачно для пользователей — можно импортировать ru.example.*; не требует правки исходников библиотеки.
- Минусы: возможны побочные эффекты (reflection, ресурсы, ServiceLoader, подписанные JAR, package-private доступ и т.п.), нужно тестировать.
- Пример (Maven Shade):
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.2.4</version>
    <configuration>
      <relocations>
        <relocation>
          <pattern>com.example.lib</pattern>
          <shadedPattern>ru.example</shadedPattern>
        </relocation>
      </relocations>
    </configuration>
  </plugin>

2) Обёртки/фасады (ручной или сгенерированный код)
- Создать пакет ru.example и в нём классы, которые наследуются от/делегируют в com.example.lib.*. Это даёт полный контроль, но много рутинной работы и лишних классов.
- Плюс: можно маппить только нужные API, контролировать поведение.

3) Переименование в исходниках
- Если вы контролируете библиотеку — лучше изменить package в исходниках и пересобрать.

4) Динамическое/байткод-переписывание
- Агент JVMTI/Instrumentation или кастомный classloader может на лету менять имена пакетов/классов. Очень сложный и хрупкий путь.

5) Языковые фичи
- В Java нет "import ... as" для типов; вы можете использовать полные квалификации или свои имена классов.
- В Kotlin/Scala есть возможность импортировать и давать локальные псевдонимы отдельным классам/функциям (import com.example.lib.Foo as FooAlias), но это не создаёт alias для всего пакета.

Особенности и предостережения
- package-private (default) доступ имеет смысл внутри одного пакета — при релокации он может поменять поведение.
- Reflection, ресурсы (путь в JAR), ServiceLoader, модульная система, подписи JAR — всё может ломаться при некорректной релокации.
- OSGi/JPMS не дают «псевдонима пакета» — только экспорты/импорты без переименования.

Резюме
- Нативно — нельзя.
- Практически: используйте build-time relocation (maven-shade/gradle-shadow/jarjar) или создайте обёртки/фасады в ru.example.
Если нужно, могу:
- показать полный пример конфигурации Maven/Gradle для релокации,
- или сгенерировать шаблоны обёрток для нескольких классов. Что предпочитаете?
Похожие вопросы