Перейти к содержимому

Relativepath maven что это

  • автор:

Понимание тега Maven «relativePath» для родительского POM

В этом руководстве мы узнаем о разрешении Parent POM Maven . Во-первых, мы обнаружим поведение по умолчанию. Затем мы обсудим возможности его настройки.

2. Разрешение родительского POM по умолчанию​

Если мы хотим указать родительский POM, мы можем сделать это, назвав groupId , ArtiftId и version , так называемую координату GAV . Maven не разрешает родительский POM, сначала выполняя поиск в репозиториях . Мы можем найти подробности в документации по модели Maven и резюмировать поведение:

  1. Если в родительской папке есть файл pom.xml , и если этот файл имеет совпадающую координату GAV, он классифицируется как родительский POM проекта.
  2. Если нет, Maven возвращается к репозиториям.

Размещение проекта Maven в другом является лучшей практикой при управлении многомодульными проектами . Например, у нас есть проект агрегатора со следующей координатой GAV:

 groupId>com.foreach.maven-parent-pom-resolutiongroupId>   artifactId>aggregatorartifactId>   version>1.0.0-SNAPSHOTversion> 

Затем мы могли бы поместить модуль в подпапку и обратиться к агрегатору как к родителю:

Таким образом, POM module1 может включать в себя этот раздел:

 artifactId>module1artifactId>   parent>   groupId>com.foreach.maven-parent-pom-resolutiongroupId>   artifactId>aggregatorartifactId>   version>1.0.0-SNAPSHOTversion>   parent> 

Нет необходимости устанавливать агрегатор POM в репозиторий. И даже не нужно объявлять module1 в POM агрегатора. Но мы должны знать, что это применимо только для локальных проверок проекта (например, при сборке проекта). Если проект разрешается как зависимость от репозитория Maven, родительский POM также должен быть доступен в репозитории.

И мы должны убедиться, что агрегатор POM имеет соответствующую координату GAV. В противном случае мы получим ошибку сборки:

 [ERROR] Non-resolvable parent POM for com.foreach.maven-parent-pom-resolution:module1:1.0.0-SNAPSHOT:  Could not find artifact com.foreach.maven-parent-pom-resolution:aggregator:pom:1.0-SNAPSHOT  and 'parent.relativePath' points at wrong local POM @ line 7, column 13 

3. Настройка расположения родительского POM​

Если родительский POM не находится в родительской папке, нам нужно использовать тег relativePath для ссылки на местоположение. Например, если у нас есть второй модуль, который должен наследовать настройки от модуля1 , а не от агрегатора, мы должны назвать родственную папку:

 artifactId>module2artifactId>   parent>   groupId>com.foreach.maven-parent-pom-resolutiongroupId>   artifactId>module1artifactId>   version>1.0.0-SNAPSHOTversion>   relativePath>../module1/pom.xmlrelativePath>   parent> 

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

4. Отключить разрешение локального файла​

Чтобы пропустить локальный поиск файлов и напрямую искать родительский POM в репозиториях Maven, нам нужно явно установить относительный путь в пустое значение:

 parent>   groupId>com.foreachgroupId>   artifactId>external-projectartifactId>   version>1.0.0-SNAPSHOTversion>   relativePath/>   parent> 

Это должно быть лучшей практикой, когда мы наследуем от внешних проектов, таких как Spring Boot .

5. IDE​

Интересно, что IntelliJ IDEA (текущая версия: 2021.1.3) поставляется с подключаемым модулем Maven, который отличается от внешних сред выполнения Maven разрешением Parent POM. Отклоняясь от схемы Maven POM , он объясняет тег relativePath следующим образом:

[…] Maven сначала ищет родительский pom в реакторе текущих строительных проектов […]

Это означает, что для внутреннего разрешения IDE положение родительского POM не имеет значения, если родительский проект зарегистрирован как проект IntelliJ Maven. Это может быть полезно для простой разработки проектов без их явного создания (если они не входят в область действия одного и того же репозитория Git). Но если мы попытаемся собрать проект с внешней средой выполнения Maven, это не удастся.

6. Заключение​

В этой статье мы узнали, что Maven не разрешает родительские POM, сначала выполняя поиск в репозиториях Maven. Он скорее ищет его локально, и мы явно должны деактивировать это поведение при наследовании от внешних проектов. Кроме того, IDE могут дополнительно разрешать проекты в рабочей области, что может привести к ошибкам при использовании внешних сред выполнения Maven.

Как всегда, код примера доступен на GitHub .

  • 1. Обзор
  • 2. Разрешение родительского POM по умолчанию
  • 3. Настройка расположения родительского POM
  • 4. Отключить разрешение локального файла
  • 5. IDE
  • 6. Заключение

Relativepath maven что это

Конкретно для версий библиотек лучше использовать стандартный механизм Мавена

В родительском pom

    org.slf4j slf4j-api 1.6.6   

В подчинённых pom

   org.slf4j slf4j-api  

Re[4]: Maven, properties

От: avpavlov
Дата: 06.02.13 14:45
Оценка: 3 (1) +1

D>Оно б с ошибкой упало, если бы не нашло родителя. А вообще, путаная вещь этот maven.

Без указания Мавен сначала идёт в локальный, а затем в удалённый репозиторий.

Если там лежит старая версия родительского pom.xml (например, исправления только что внесли, а install/deploy ещё не делали), то она и будет использоваться.

Если указан , то Мавен сначала пойдёт по структуре проекта, а затем уже в репозитории.

Всё указанное выше — для Мавен 3, в Мавен 2 было попроще.

Re[9]: Maven, properties

От: dimgel http://dimgel.ru/
Дата: 09.02.13 13:18
Оценка: 6 (1)

Здравствуйте, ., Вы писали:

.>Тупо ещё система сборки — неинтересно. Мавен поддерживается в разных IDE. Открываешь проект и сразу прописаны все свойства проекта, зависимости, скачиваются исходники всех зависимостей, предлагаются таргеты для запуска jetty:run и прочее. Как с этим дела в sbt?

Нормально, есть плагины:

$ sbt eclipse
генерирует/обновляет файлы проекта
$ sbt gen-idea
генерирует/обновляет файлы проекта
$ sbt gen-idea sbt-classifiers
в том числе прописывает собственно дескриптор проекта отдельным модулем со всеми classpath-ами и т.п., так чтобы его можно было тоже нормально редактировать.

После вызова gen-idea и переключение в окно Idea, она обнаруживает, что её файлы проекта изменились, и предлагает перестартовать. Это конечно не та совершенно роскошная поддержка maven-проектов в Idea, но вполне удобно, тем более, что это не каждый день приходится делать. Вообще, информация об убогости тулзов уже в значительной степени устарела, мне так кажется. Глюки с синтакс-подсветкой в Idea крайни редки, за исключением разработки макросов, где приходится либо юзать eclipse (который сам по себе убог донельзя, безотносительно качества scala-плагина, которое в целом уже вполне сносное), либо продолжать мучиться в Idea, игнорируя богато раскрашенным красным цветом экран.

Maven, properties

От: Crystalizer
Дата: 06.02.13 13:57
Оценка:

Хочу в pom.xml модуля так ссылатся на версию spring

  org.springframework spring-orm $ 

В главном pom.xml это объявлено так:

  UTF-8 1.6 3.0.1.RELEASE 

Проблема:
pom.xml модуля не видит property и пишет что не может найти путь к репозиторию, где часть пути — это $

Вопрос: как исправить?
С чем это может быть связано?
вроде по ссылкам поподаю из главное pom на модуль и обратно.

Re: Maven, properties

От: dimgel http://dimgel.ru/
Дата: 06.02.13 14:08
Оценка:

Здравствуйте, Crystalizer, Вы писали:

C>pom.xml модуля не видит property и пишет что не может найти путь к репозиторию, где часть пути — это $

В pom модуля присутствует на главный модуль?

Re[2]: Maven, properties

От: Crystalizer
Дата: 06.02.13 14:10
Оценка:

Здравствуйте, dimgel, Вы писали:

D>В pom модуля присутствует на главный модуль?

да, они друг друга видят

  4.0.0 a.b.c C 1.0  a.b.c capi capi 1.0

Re[2]: Maven, properties

От: avpavlov
Дата: 06.02.13 14:22
Оценка:

A>Конкретно для версий библиотек лучше использовать стандартный механизм Мавена

Ну а если так уж хочется сделать неправильно, то в подчиненных помах надо теперь (начиная с Мавен3) прописывать путь

  a.b.c C 1.0 ../pom.xml 

Maven 3 no longer resolves parent POMs from the local project checkout unless the child POM’s element is accurate, whether explicitly given or using the default value. This improves consistency regarding the build result when building the child project in isolation and when performing a reactor build that includes the parent project. In Maven 2, building the child project in isolation could fail while the reactor build would succeed to resolve the parent.

Re[2]: Maven, properties

От: Crystalizer
Дата: 06.02.13 14:23
Оценка:

Здравствуйте, avpavlov, Вы писали:

A>Конкретно для версий библиотек лучше использовать стандартный механизм Мавена

Re[3]: Maven, properties

От: Crystalizer
Дата: 06.02.13 14:24
Оценка:

вобщем как-то исправил.
кажеца в соседнем модуле была неправильная ссылка или ещё что. так и не понял, но теперь уже ошибки нет

Re[3]: Maven, properties

От: avpavlov
Дата: 06.02.13 14:26
Оценка:

нет, посмотри внимательнее

Re[3]: Maven, properties

От: dimgel http://dimgel.ru/
Дата: 06.02.13 14:35
Оценка:

Здравствуйте, avpavlov, Вы писали:

A>Ну а если так уж хочется сделать неправильно, то в подчиненных помах надо теперь (начиная с Мавен3) прописывать путь

A>

A> ../pom.xml A>

Оно б с ошибкой упало, если бы не нашло родителя. А вообще, путаная вещь этот maven.

Re[4]: Maven, properties

От: Crystalizer
Дата: 06.02.13 14:35
Оценка:

Здравствуйте, avpavlov, Вы писали:

A>нет, посмотри внимательнее

а, dependencyManagement — понял, спасибо

Re[4]: Maven, properties

От: Crystalizer
Дата: 06.02.13 14:37
Оценка:

Здравствуйте, dimgel, Вы писали:

D>Здравствуйте, avpavlov, Вы писали:

A>>Ну а если так уж хочется сделать неправильно, то в подчиненных помах надо теперь (начиная с Мавен3) прописывать путь

A>>

A>> ../pom.xml A>>

D>Оно б с ошибкой упало, если бы не нашло родителя. А вообще, путаная вещь этот maven.

ждём графической версии

Re[5]: Maven, properties

От: dimgel http://dimgel.ru/
Дата: 06.02.13 14:41
Оценка:

Здравствуйте, Crystalizer, Вы писали:

D>>А вообще, путаная вещь этот maven.

C>ждём графической версии

Горбатого могила исправит. Я не так давно наконец-то пересел с maven на sbt, в котором проект описывается scala-исходником — и НЕ НАРАДУЮСЬ.

Re[6]: Maven, properties

От: Crystalizer
Дата: 06.02.13 14:58
Оценка:

Здравствуйте, dimgel, Вы писали:

D>Здравствуйте, Crystalizer, Вы писали:

D>>>А вообще, путаная вещь этот maven.

C>>ждём графической версии

D>Горбатого могила исправит. Я не так давно наконец-то пересел с maven на sbt, в котором проект описывается scala-исходником — и НЕ НАРАДУЮСЬ.

эх, сколько ж можно уже этих тулзов клепать?

Re[7]: Maven, properties

От: dimgel http://dimgel.ru/
Дата: 06.02.13 15:05
Оценка:

Здравствуйте, Crystalizer, Вы писали:

D>>Горбатого могила исправит. Я не так давно наконец-то пересел с maven на sbt, в котором проект описывается scala-исходником — и НЕ НАРАДУЮСЬ.

C>эх, сколько ж можно уже этих тулзов клепать?

Описывать проект на высокоуровневом языке — это новое поколение тулзов, гораздо более мощных, выразительных, гибких и удобных. После этой идиотской моды всё подряд пихать в XML.
Я могу создавать кастомные таски прямо в исходнике описания проекта в две строчки, вместо того, чтобы клепать отдельный плагин, разбираясь с API для плагинов.
Могу поднимать свойства проекта откуда захочу, вообще чё хочу могу делать, чего maven-у и не снилось.
Не говоря уже о том, что в исходнике проекта на статически-типизированной скале гораздо сложнее наделать глупых ошибок, зато гораздо проще искать концы: shift+click на имя свойства — и я в исходном коде sbt, где это свойство объявляется.

Re[8]: Maven, properties

От: Crystalizer
Дата: 06.02.13 15:13
Оценка:

Здравствуйте, dimgel, Вы писали:

D>Здравствуйте, Crystalizer, Вы писали:

D>>>Горбатого могила исправит. Я не так давно наконец-то пересел с maven на sbt, в котором проект описывается scala-исходником — и НЕ НАРАДУЮСЬ.

C>>эх, сколько ж можно уже этих тулзов клепать?

D>Описывать проект на высокоуровневом языке — это новое поколение тулзов.

Re[9]: Maven, properties

От: dimgel http://dimgel.ru/
Дата: 06.02.13 15:16
Оценка:

Здравствуйте, Crystalizer, Вы писали:

D>>Описывать проект на высокоуровневом языке — это новое поколение тулзов.

C>может тогда Gradle?
Я его тоже имел в виду, но для скалы удобнее нативный, на скале же написанный sbt.

Re[10]: Maven, properties

От: Crystalizer
Дата: 06.02.13 15:21
Оценка:

Здравствуйте, dimgel, Вы писали:

D>Здравствуйте, Crystalizer, Вы писали:

D>>>Описывать проект на высокоуровневом языке — это новое поколение тулзов.

C>>может тогда Gradle?
D>Я его тоже имел в виду, но для скалы удобнее нативный, на скале же написанный sbt.

а
вот бы на java

Re[11]: Maven, properties

От: dimgel http://dimgel.ru/
Дата: 06.02.13 15:32
Оценка:

Здравствуйте, Crystalizer, Вы писали:

C>>>может тогда Gradle?
D>>Я его тоже имел в виду, но для скалы удобнее нативный, на скале же написанный sbt.

C>а
C>вот бы на java

Жаву sbt тоже умеет компилять, хотя удобнее конечно, когда язык везде один. А groovy этот, в gradle используемый, вообще динамически типизированный.

Например, у меня в проекте есть модуль genstructure, который считывает структуру базы в дерево объектов и java-сериализует его в ресурсы другого модуля. Он компилируется и тут же запускается, выглядит это так:

 lazy val `dev-genstructure` = subproject( // subproject() - моя вспомогательная shortcut-функция "dev-genstructure", // Каталог проекта, полное имя формирует subproject() genstructureTask 

Этот модуль не деплоится, он нужен только на этапе сборки. Эта сериализованная информация потом используется и при сборке (модулем dev-genmodel, генерирующем сорцы entity-классов) и в рантайме.

Re[12]: Maven, properties

От: avpavlov
Дата: 06.02.13 15:39
Оценка:

Для внутренних проектов сойдет, а вот для публичных не очень.

Сейчас я беру публичный проект и спокойно ориентируюсь в pom.xml, потому что он стандартный.

А когда я возьму такой скрипт как у тебя, то чего он делает можно будет понять только после серьёзного анализа.

Re[13]: Maven, properties

От: dimgel http://dimgel.ru/
Дата: 06.02.13 16:21
Оценка:

Здравствуйте, avpavlov, Вы писали:

A>Для внутренних проектов сойдет, а вот для публичных не очень.

A>Сейчас я беру публичный проект и спокойно ориентируюсь в pom.xml, потому что он стандартный.

A>А когда я возьму такой скрипт как у тебя, то чего он делает можно будет понять только после серьёзного анализа.

Публичные либы не требуют всяких наворотов, так что скрипт будет простой.

Скрипт, функционально идентичный pom.xml, будет в несколько раз короче и соответственно легче читаться: сравни, к примеру, "com.blablabla" % "artifact" % "version" с той тонной визуального шума, что в pom.

Ну а если просто зависимости посмотреть, дык эта дрянь умеет генерить pom и деплоиться в maven-репы.

Re[8]: Maven, properties

От: .
Дата: 09.02.13 13:11
Оценка:

Здравствуйте, dimgel, Вы писали:

d> Описывать проект на высокоуровневом языке — это новое поколение тулзов, гораздо более мощных, выразительных, гибких и удобных. После этой идиотской моды всё подряд пихать в XML.
d> Я могу создавать кастомные таски прямо в исходнике описания проекта в две строчки, вместо того, чтобы клепать отдельный плагин, разбираясь с API для плагинов.
d> Могу поднимать свойства проекта откуда захочу, вообще чё хочу могу делать, чего maven-у и не снилось.
d> Не говоря уже о том, что в исходнике проекта на статически-типизированной скале гораздо сложнее наделать глупых ошибок, зато гораздо проще искать концы: shift+click на имя свойства — и я в исходном коде sbt, где это свойство объявляется.
Тупо ещё система сборки — неинтересно. Мавен поддерживается в разных IDE. Открываешь проект и сразу прописаны все свойства проекта, зависимости, скачиваются исходники всех зависимостей, предлагаются таргеты для запуска jetty:run и прочее. Как с этим дела в sbt?

Introduction to the POM

A Project Object Model or POM is the fundamental unit of work in Maven. It is an XML file that contains information about the project and configuration details used by Maven to build the project. It contains default values for most projects. Examples for this is the build directory, which is target ; the source directory, which is src/main/java ; the test source directory, which is src/test/java ; and so on. When executing a task or goal, Maven looks for the POM in the current directory. It reads the POM, gets the needed configuration information, then executes the goal.

Some of the configuration that can be specified in the POM are the project dependencies, the plugins or goals that can be executed, the build profiles, and so on. Other information such as the project version, description, developers, mailing lists and such can also be specified.

Super POM

The Super POM is Maven's default POM. All POMs extend the Super POM unless explicitly set, meaning the configuration specified in the Super POM is inherited by the POMs you created for your projects.

You can see the Super POM for Maven 3.6.3 in Maven Core reference documentation.

Minimal POM

The minimum requirement for a POM are the following:

  • project root
  • modelVersion - should be set to 4.0.0
  • groupId - the id of the project's group.
  • artifactId - the id of the artifact (project)
  • version - the version of the artifact under the specified group

Here's an example:

 4.0.0 com.mycompany.app my-app 1 

A POM requires that its groupId, artifactId, and version be configured. These three values form the project's fully qualified artifact name. This is in the form of ::. As for the example above, its fully qualified artifact name is "com.mycompany.app:my-app:1".

Also, as mentioned in the first section, if the configuration details are not specified, Maven will use their defaults. One of these default values is the packaging type. Every Maven project has a packaging type. If it is not specified in the POM, then the default value "jar" would be used.

Furthermore, you can see that in the minimal POM the repositories were not specified. If you build your project using the minimal POM, it would inherit the repositories configuration in the Super POM. Therefore when Maven sees the dependencies in the minimal POM, it would know that these dependencies will be downloaded from https://repo.maven.apache.org/maven2 which was specified in the Super POM.

Project Inheritance

Elements in the POM that are merged are the following:

  • dependencies
  • developers and contributors
  • plugin lists (including reports)
  • plugin executions with matching ids
  • plugin configuration
  • resources

The Super POM is one example of project inheritance, however you can also introduce your own parent POMs by specifying the parent element in the POM, as demonstrated in the following examples.

Example 1

The Scenario

As an example, let us reuse our previous artifact, com.mycompany.app:my-app:1. And let us introduce another artifact, com.mycompany.app:my-module:1.

 4.0.0 com.mycompany.app my-module 1 

And let us specify their directory structure as the following:

. |-- my-module | `-- pom.xml `-- pom.xml

Note: my-module/pom.xml is the POM of com.mycompany.app:my-module:1 while pom.xml is the POM of com.mycompany.app:my-app:1

The Solution

Now, if we were to turn com.mycompany.app:my-app:1 into a parent artifact of com.mycompany.app:my-module:1,we will have to modify com.mycompany.app:my-module:1's POM to the following configuration:

com.mycompany.app:my-module:1's POM

 4.0.0 com.mycompany.app my-app 1  com.mycompany.app my-module 1 

Notice that we now have an added section, the parent section. This section allows us to specify which artifact is the parent of our POM. And we do so by specifying the fully qualified artifact name of the parent POM. With this setup, our module can now inherit some of the properties of our parent POM.

Alternatively, if you want the groupId or the version of your modules to be the same as their parents, you can remove the groupId or the version identity of your module in its POM.

 4.0.0 com.mycompany.app my-app 1  my-module 

This allows the module to inherit the groupId or the version of its parent POM.

Example 2

The Scenario

However, that would work if the parent project was already installed in our local repository or was in that specific directory structure (parent pom.xml is one directory higher than that of the module's pom.xml ).

But what if the parent is not yet installed and if the directory structure is as in the following example?

. |-- my-module | `-- pom.xml `-- parent `-- pom.xml
The Solution

To address this directory structure (or any other directory structure), we would have to add the element to our parent section.

 4.0.0 com.mycompany.app my-app 1 ../parent/pom.xml  my-module 

As the name suggests, it's the relative path from the module's pom.xml to the parent's pom.xml .

Project Aggregation

Project Aggregation is similar to Project Inheritance. But instead of specifying the parent POM from the module, it specifies the modules from the parent POM. By doing so, the parent project now knows its modules, and if a Maven command is invoked against the parent project, that Maven command will then be executed to the parent's modules as well. To do Project Aggregation, you must do the following:

  • Change the parent POMs packaging to the value "pom".
  • Specify in the parent POM the directories of its modules (children POMs).

Example 3

The Scenario

Given the previous original artifact POMs and directory structure:

com.mycompany.app:my-app:1's POM

 4.0.0 com.mycompany.app my-app 1 

com.mycompany.app:my-module:1's POM

 4.0.0 com.mycompany.app my-module 1 

directory structure

. |-- my-module | `-- pom.xml `-- pom.xml
The Solution

If we are to aggregate my-module into my-app, we would only have to modify my-app.

 4.0.0 com.mycompany.app my-app 1 pom my-module  

In the revised com.mycompany.app:my-app:1, the packaging section and the modules sections were added. For the packaging, its value was set to "pom", and for the modules section, we have the element my-module . The value of is the relative path from the com.mycompany.app:my-app:1 to com.mycompany.app:my-module:1's POM (by practice, we use the module's artifactId as the module directory's name).

Now, whenever a Maven command processes com.mycompany.app:my-app:1, that same Maven command would be ran against com.mycompany.app:my-module:1 as well. Furthermore, some commands (goals specifically) handle project aggregation differently.

Example 4

The Scenario

But what if we change the directory structure to the following:

. |-- my-module | `-- pom.xml `-- parent `-- pom.xml

How would the parent POM specify its modules?

The Solution

The answer? - the same way as Example 3, by specifying the path to the module.

 4.0.0 com.mycompany.app my-app 1 pom ../my-module  

Project Inheritance vs Project Aggregation

If you have several Maven projects, and they all have similar configurations, you can refactor your projects by pulling out those similar configurations and making a parent project. Thus, all you have to do is to let your Maven projects inherit that parent project, and those configurations would then be applied to all of them.

And if you have a group of projects that are built or processed together, you can create a parent project and have that parent project declare those projects as its modules. By doing so, you'd only have to build the parent and the rest will follow.

But of course, you can have both Project Inheritance and Project Aggregation. Meaning, you can have your modules specify a parent project, and at the same time, have that parent project specify those Maven projects as its modules. You'd just have to apply all three rules:

  • Specify in every child POM who their parent POM is.
  • Change the parent POMs packaging to the value "pom" .
  • Specify in the parent POM the directories of its modules (children POMs)

Example 5

The Scenario

Given the previous original artifact POMs again,

com.mycompany.app:my-app:1's POM

 4.0.0 com.mycompany.app my-app 1 

com.mycompany.app:my-module:1's POM

 4.0.0 com.mycompany.app my-module 1 

and this directory structure

. |-- my-module | `-- pom.xml `-- parent `-- pom.xml
The Solution

To do both project inheritance and aggregation, you only have to apply all three rules.

com.mycompany.app:my-app:1's POM

 4.0.0 com.mycompany.app my-app 1 pom ../my-module  

com.mycompany.app:my-module:1's POM

 4.0.0 com.mycompany.app my-app 1 ../parent/pom.xml  my-module 

NOTE: Profile inheritance the same inheritance strategy as used for the POM itself.

Project Interpolation and Variables

One of the practices that Maven encourages is don't repeat yourself. However, there are circumstances where you will need to use the same value in several different locations. To assist in ensuring the value is only specified once, Maven allows you to use both your own and pre-defined variables in the POM.

For example, to access the project.version variable, you would reference it like so:

One factor to note is that these variables are processed after inheritance as outlined above. This means that if a parent project uses a variable, then its definition in the child, not the parent, will be the one eventually used.

Available Variables

Project Model Variables

Any field of the model that is a single value element can be referenced as a variable. For example, $ , $ , $ and so on. Refer to the POM reference to see a full list of properties.

These variables are all referenced by the prefix " project. ". You may also see references with pom. as the prefix, or the prefix omitted entirely - these forms are now deprecated and should not be used.

Special Variables
project.basedir The directory that the current project resides in.
project.baseUri The directory that the current project resides in, represented as an URI. Since Maven 2.1.0
maven.build.timestamp The timestamp that denotes the start of the build (UTC). Since Maven 2.1.0-M1

The format of the build timestamp can be customized by declaring the property maven.build.timestamp.format as shown in the example below:

 . yyyy-MM-dd'T'HH:mm:ss'Z'  . 

The format pattern has to comply with the rules given in the API documentation for SimpleDateFormat. If the property is not present, the format defaults to the value already given in the example.

Properties

You are also able to reference any properties defined in the project as a variable. Consider the following example:

 . 3.0   org.apache.maven maven-artifact $ org.apache.maven maven-core $  . 

Relativepath maven что это

# MAVEN + JAVA + SPRING BOOT + Hibernate ### Начало В файлик `pom.xml` прописываем следующее: ```xml org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-security org.springframework.boot spring-boot-starter-data-jpa org.postgresql postgresql 42.2.5 org.projectlombok lomboktrue org.modelmapper modelmapper 2.3.2 ``` Суть простая: "парент" задаёт типо обобщение для пакетов зависимостей (в частности, номер версии - чтобы его каждому пакету руками не писать). Затем подключаем `spring-boot-starter-web` - это спринг бут со встроенным Томкатом Затем `spring-boot-starter-data-jpa` - эт чтоб с хиьером работать через JPA (подробностей не знаю, ту скорее всего лежит `JDBC` и т.п.). Далее `postgresql` - чтобы к постгресу коннетиться `lombok` - чтобы `@Data` превращалось в сеттеры-геттеры `modelmapper` - чтобы DTO'хи руками не мапить __:)__ Для реализации аутентификации надо ещё подключить пакет `spring-boot-starter-security` - потом пишем отдельный класс конфигурирования этого дела и получаем секурити. Чтоб собрать без `tomcat-embedded` надо его отдельно прописать в зависимости и добавить `provided`: ```xml org.springframework.boot spring-boot-starter-tomcat provided ``` После чего меняем `jar` на `war` и получаем варник, который подсовываем стендэлон-томкату __(:__ ### Спринг-бут приложение Главный класс нашего приложения выглядит вот так: ```java @SpringBootApplication public class LsrServer < static public void main(String args[]) < SpringApplication.run(LsrServer.class, args); >> ``` Аннотация х.з. зачем нужна, но нужна, а в теле всё что мы делаем это скармливаем наш "главный" класс спринговому стартеру ### HTTP REST Обработчики HTTP-запросов (а-ка "контроллеры") пишутся так: ```java @RestController @RequestMapping("/api") public class ExampleController < @GetMapping("/test") public MapgetHelloWorld() < HashMapresult = new HashMap<>(); result.put("Hello", "World!"); return result; > > ``` Т.е. просто пишем класс и аннотацией `@RestController` говорим спрингу, что это, собственно, __REST__-контроллер. А аннотация `@RequestMapping` позволяем задать "базовый" путь для все обработчиков этого класса (чтоб каждому не дописывать один и тот же кусок) Внутри класса пишем публичные методы, которые что-нибудь возвращают или не возвращают ничего (`void`) - спринг сам это дело будет преобразовывать в джейсон (или ещё в чо-нить, во что вы его попросите - по-дефолту он юзает джейсон, с которым работает с помощью либы `jackson`, которую он сам подтягивает) Аннотация `@GetMapping` позволяет указать тип метода (в данном случае `GET`) и дополнительный путь (его можно и не указывать). Есть аналогичные аннотации для всех остальных HTTP-методов Данные из запроса передаются в запрос с помощью аннотаций `@RequestBody`, `@PathVariable` и `@RequestParam` следующим образом: ```java @PostMapping("/test/") public void postTest(@RequestBody SomeDTO body, @RequestParam("some_param") String someParam, @PathVariable("id") int id) < // todo something >``` Спринг сделает за нас всю грязную работу и тело запроса окажется в `body`, строка `helloworld` (из строки запроса типо такой: `localhost:/test/13?some_param=helloworld`) - в переменной `someParam`, а число `13` попадёт в переменную `id` __B-)__ (Если имя Java-переменной и параметра в запросе совпадают, то тогда у аннотации можно не писать скобки и имя параметра в ковычках внутри) У аннотации `@RequestParam` есть ещё поля `required` и `defaultValue`, которые нужны сами догадываетесь зачем __;-)__ Так же, в параметрах запроса можно юзать переменные (т.е. когда сам роут несёт смысловую нагрузку), с помощью аннотации `@PathVariable`, пример: ```java @GetMapping("//test") public void getTest(@PathParam("id") int id) < // todo something >``` Суть проста: запрос вида `localhost:/api/13/test` попадёт в этот метод-обработчик и в переменной `id` окажется число 13 (`/api` в начале запроса это потому что в примере выше мы использовали `@RequestMapping("/api")` для всего нашего класса) ### Exceptions Чтобы ответить серверу что-то кроме `200 OK` нужно выбросить исключение. Готовых нет (я не смог найти), так что пишем свои: ```java @ResponseStatus(value = HttpStatus.BAD_REQUEST) public class BadRequestException extends RuntimeException < public BadRequestException(String message) < super(message); >> ``` Спринг отлавливает всё унаследованное от `RuntimeException` что мы забудем перехватить в контроллере/репозиории (или сами нарочно выбросим) и сам формирует из него ответ клиенту. Аннотация нужна чтобы задать код ответа -- без неё спринг будет пихать `500 Internal Server Error`. ### DTO Согласно концепции "Model-View-Controller" принято для хранения данных, для их обработки и для передачи использовать разные представления (т.е. разные "классы" в нашем случае), так что для апихи создают отдельный набор, в названия которого добавляют "DTO" (ранее в примере это уже было: `. @RequestBody SomeDTO body . `). Для "конвертации" данных из одного объекта в другой юзают библиотеку "ModelMapper". Она довольно умная и при совпадении имён меременных сама догадывается откуда куда копировать данные. Если же у нас названия отличаются, или же сама структура объектов разная, то нужно "помочь" моделмапперу - создать соответствующий бин, в котором "вручную" промапить "сложные" поля (ну или вообще все, если мы хотим реализовать какое-то хитрое отображение данных): ```java @Configuration public class ModelMapperProducer < @Bean public ModelMapper modelMapper() < ModelMapper modelMapper = new ModelMapper(); modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT); modelMapper.getConfiguration().setPropertyCondition(Conditions.isNotNull()); modelMapper.typeMap(TestObject.class, TestObjectDTO.class) .setPostConverter(context ->< context.getDestination().name = context.getSource().fullName; return context.getDestination(); >); modelMapper.typeMap(TestObjectDTO.class, TestObject.class) .setPostConverter(context -> < context.getDestination().fullName = context.getSource().name; return context.getDestination(); >); return modelMapper; > > ``` В этом примере показаны два преобразования (в одну сторону и в обратную - зачастую ДТОха используется и для того чтобы "отдавать" данные, и для того чтобы их "принимать"). А так же здесь заданы две популярные настройки: "строгое" совпадение имён параметров (иначе моделМаппер начнёт пытаться "угадать" похожие имена и можно получить мяаасоо), а так же мы говорим мапперу обрабатывать только те поля (в "исходном" объекте), которые `!= null` (насчёт подробностей я пока не в курсе) Пример самой DTO: ```java @Data public class HumanDTO < String name; int age; >``` Как бы, проще некуда - просто набор полей __(:__ ### Entity Работа с БД осуществляется по модели JPA (кароч это "накрученный" ООП). Класс, который надо "засунуть" в БД помечаем аннотациями `@Entity` и `@Data`. Имя таблицы в БД будет совпадать с именем вашего класса - если вы хотите это изменить, то нужна аннотация `@Table` (например `@Table(name="test_table")`) Пример: ```java @Entity @Data public class Boy < @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(updatable = false, nullable = false) protected Long id; String name; int age; @ManyToMany @JoinTable(name = "boys_and_girls", joinColumns = @JoinColumn(name = "boy_id"), inverseJoinColumns = @JoinColumn(name = "girl_id")) Setfriends = new HashSet<>(); public int hashCode() < return (name + age).hashCode(); >> ``` `id` здесь помечено `@Id`, что задаёт "простой" primare key - уникальный идентификатор записи в БД'шной таблице. К слову, это самый праймари кей бывает и ещё и "композитым" - вещь нужная (как мне говорят). Все переменные к таком классе "используются" хибернейтом в качестве полей таблицы БД (т.е. даже вообще никак не помеченные, как, например, `name` и `age` в этом примере) - чтобы хибернейт "игнорил" поле его надо пометить аннотацией `@Transient` (и да, мноогие аннотации есть и в яве, и в хибернейте - так вот, надо юзать те что в яве. ) Аннотация `@Column` нужна только для того, чтобы задавать дополнительные "настройки" для поля. В примере выше переопределён метод `hashCode()` - это нужно в случае когда ваша "таблица" содержит объекты типа `HashSet` - без этого переопределния выполучите `StackOverflowError`, потому что будет происходить очень странная рекурсивная чёрная магия __:-|__ (Собственно, это относится ко всем hash-объектам, например _HashMap_) Далее. в нашем классе `Boy` есть "сложный параметр" `friends` - в данном случае это ссылка на другую таюлицу БД, да ещё с "двусторонней" связью между данными. К слову, есть аннотация `@Embedded`, наличие которой заставляет хибернейт "скопипастить" содержимое этого класса, т.е. как `#include` в сях __(:__ ### Связи между таблицами Есть два способа связи: `@JoinTable` и `@JoinColumn`: в первом создаётся отдельная таблица, хранящая "связи", а во втором в "целевую" таблицу просто добавляется столбец, в котором хранится айдишник ссылающейся на него записи исходной таблицы. При отсутствии этих аннотаций хибер по-дефолту юзает `@JoinTable`. ##### @OneToOne Дефолтный `fetch` тут `EAGER` Просто ссыль на запись в другой таблице, т.е. когда одной строке в таблице А соответствует одна строка в таблице Б. Если тут прописать `@JoinColumn`, то "столбец связи" будет помещён в "эту" таблицу (это ведь логично: кому связь нужна, тот и хранит о ней информацию). Можно вручную указать таблицу, в которой должен быть этот столбец: `@JoinColumn(name = "field_name", table = "table_name")`, но таблица уже должна существовать, т.е. хибер сам её создавать/модифицировать не хочет, зараза :neutral_face: ##### @OneToMany Дефолтный `fetch` тут `LAZY` ##### @ManyToOne Дефолтный `fetch` тут `EAGER` ##### @ManyToMany Дефолтный `fetch` тут `LAZY` ### Logger Прописываем в каждом классе `private final Log logger;` (который из `org.apache.commons.logging.Log`) и в конструкторе класса пишем `this.logger = LogFactory.getLog(this.getClass());` - всё, теперь у нас есть спринговый логгер. Можем логировать всё чо душе угодно (какие методы у него и как вызывать - сами догадаетесь).

Last changed by

Java desktop/back-end developer, ex electronics engineer

Add a comment

Read more

OpenVPN и локальный Dnsmasq
AWS (Amazon Web Services) - краткое руководство

Published on HackMD

Sign in

By clicking below, you agree to our terms of service.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *