Tag Archives: Mimbolovemaven

Сайт проекта средствами maven

Written by elwood

apache_maven

В рамках продолжения работ по плагину FreeMarker для MyBatis нужно было сделать сайт проекта, по аналогии с тем, как это сделано у mybatis-velocity. С сайтами такого рода я сталкивался неоднократно, но до этого не задумывался о том, как такие сайты делаются. Поэтому пришлось «реверсить» метод создания сайта. Посмотрев на верстку и погуглив, я обнаружил, что это – результат выполнения команды mvn site. Однако на исходниках mybatis-velocity эта команда почему-то выдавала другой результат: сайт был похож, но стили были старые, отсутствовал логотип, и не было целой группы разделов «Project Reports». Допустив, что часть конфигурации находится в родительском pom.xml и берётся откуда-то из другого места, я стал шаманить с конфигами, пытаясь добиться, чтобы mvn site выдавал точно такой сайт, который был выложен на github-pages. Через некоторое время мне это удалось, и я сделал всё по аналогии для своего проекта. И заодно решил написать гайд по тому, как это сделать.

Итак, в мавне есть встроенный механизм для генерации шаблонных сайтов проектов. В сгенерированном сайте автоматом будет инфа о полученном артефакте, о том, какие зависимости у него есть, как прописать артефакт к себе в pom.xml, список участников проекта, и ещё много разных отчётов. По умолчанию список генерируемых отчётов весьма велик, его можно уменьшить, а можно добавить ещё 🙂 Для того, чтобы вся балалайка завертелась, нужно запилить site.xml. В нём прописываются настройки меню, внешнего вида сайта. Можно выбрать плагин для стилей – по умолчанию будет старенький стиль, fluido на бутстрапе выглядит поприкольнее. В папке xdocs уже пишется сам контент. Формат простой и интуитивно понятный – я за полчаса по аналогии забацал свою страничку «Getting started». Одно тонкое место – чтобы избежать лишних пробелов до и после кодовой разметки, нужно чтобы не было пробелов между тегами <source/> и собственно исходным кодом. Ну и очень желательно уметь использовать <![CDATA[]]>.

Далее, дополнительные плагины. Очень рекомендую встроить javadocs. Это, думаю, самое полезное. Для того, чтобы отчёт сгенерился вместе с остальными, достаточно добавить его в <repoting/>. У меня был какой-то баг при генерации джавадоков, почему-то не компилировались классы из test. Пришлось заигнорить goal javadoc-test.

После того, как мавно сделает вам сайт, вы можете его просто залить на GitHub Pages – либо в отдельный репозиторий, либо в этот же проект веткой gh-pages.

В остальном проще не расписывать подробно, что к чему, а просто дать ссылку на пример того, как это настроено в моём случае: https://github.com/elw00d/mybatis-freemarker. Можно просто копировать конфиги и изменять по своему усмотрению.

Как опубликовать maven-артефакт в jCenter

Written by elwood

Недавно я случайным образом написал плагин для MyBatis. Написал тесты, readme, все дела. И даже прикрутил бейдж от travis-ci. Но самое главное ещё только предстояло сделать. А именно – запилить этот мейвеновский пакет в какой-нибудь публичный репозиторий. Я никогда ещё этого не делал, и сначала было пошёл смотреть, как опубликовать свой артефакт на Maven Central. Нашёл статью “Публикация артефакта в Maven Central через Sonatype OSS Repository Hosting Service”, полистал, и призадумался. Что-то всё как-то больно сложно. И вспомнил, что gretty, один из моих любимых плагинов для gradle, хостит свои релизы на jcenter. Решил попробовать – и вуаля ! Всё получилось. Единственный затык был связан с тем, что я заливал файлы в неправильный путь. И ещё пришлось догадаться сделать pom-файл отдельно, а не надеяться на парсер джарника. Чтобы вы не повторяли моих ошибок и туплений, напишу краткий гайд о том, как опубликовать простой обычный артефакт в jcenter.

  1. Сходите на https://bintray.com и зарегистрируйтесь
  2. В интерфейсе кабинета создайте свою организацию, внутри неё – maven репозиторий (с произвольным названием), далее внутри репозитория создайте пакет, а внутри пакета – версию. Версия должна быть release, то есть не содержать суффикса “SNAPSHOT”
  3. Подготовьте 3 файла:
    • project-1.0.jar – этот файл обычно делается командой mvn clean package
    • project-1.0-sources.jar – здесь можно попробовать команду mvn source:jar
    • project-1.0.pom – а этот файл делается простым переименованием вашего pom.xml
  4. В контексте версии в веб-интерфейсе перейтиде к странице загрузки файлов. Выберите сразу 3 файла и перетащите их в броузер. Вы должны будете увидеть что-то типа этого:

    bintray-uploading

    Жмите Accept, и пути будут выставлены корректно, согласно координатам, указанным в вашем pom-файле.

  5. Теперь bintray предложит опубликовать загруженные артефакты. Не отказывайтесь.
  6. Далее возвращаемся к версии, наводим мышку на Maven Central, и выбираем опцию Synchronize with jCenter. Если всё сделано правильно, то система примет этот запрос, и теперь остается некоторое время подождать, пока сотрудник jCenter рассмотрит его. Вам придет письмо на email и уведомление по внутренней почте.
  7. Артефакт успешно опубликован в jcenter и доступен для загрузки ! Теперь его можно просто брать и использовать, в мейвене :
    <repositories>
        <repository>
            <id>jcenter</id>
            <url>http://jcenter.bintray.com</url>
        </repository>
    </repositories>
     
    <dependencies>
        <dependency>
            <groupId>org.mybatis.scripting</groupId>
            <artifactId>mybatis-freemarker</artifactId>
            <version>1.1</version>
        </dependency>
    </dependencies>

    или в Gradle:

    repositories {
        jcenter()
    }
     
    dependencies {
        compile("org.mybatis.scripting:mybatis-freemarker:1.1")
    }

Далее в планах все-таки попробовать запилить свой пакет в Maven Central, по результатам постараюсь отписаться тоже.

Готовим maven правильно: deployment в Tomcat

Written by elwood

cargo-banner

Задача

Есть многомодульный проект, собираемый с помощью maven. Среди модулей имеются несколько WAR-приложений, которые должны деплоиться в сервлет-контейнер (рассмотрим Томкат, но всё применимо и к любому другому контейнеру или серверу приложений). Причём желательно иметь возможность выборочно собирать и деплоить только одно из этих приложений. Развёртываться всё это добро должно уметь как в локальный контейнер программиста, так и на удалённый тестовый сервер.

Решение

У нас есть один главный модуль (тот, у которого packaging = pom) и несколько модулей. В pom.xml главного модуля мы пропишем два набора профилей. Один набор профилей будет отвечать за то, собирать ли указанный модуль или нет. Второй набор профилей будет отвечать за настройки окружения. Таким образом, мы превращаем мейвеновские профили в аналог USE-флагов в Gentoo Linux. Также в pom.xml главного модуля мы сконфигурируем плагин cargo-maven2-plugin, указав ему skip = true. А в тех дочерних модулях, которые предполагаются к развёртыванию, мы этот флаг установим в false. Таким образом, мы сможем вызывать cargo:deploy для главного модуля, но срабатывать он будет только у тех дочерних, которые мы укажем. Иные варианты, к сожалению, работать не будут (например, если конфигурировать плагин для дочернего модуля и вызывать напрямую у него, то при наличии зависимостей maven не сможет собрать модуль). А два набора профилей дадут нам возможность выборочно собирать и развёртывать приложения туда, куда нам хочется.

Код

pom.xml главного модуля:

<modules>
  <!-- Модули, собираемые всегда -->
  <module>common-dependency</module>
</modules>
<packaging>pom</packaging>
 
<profiles>
  <!-- Профили, относящиеся к настройкам окружения - при сборке мы должны указать только 1 профиль -->
  <profile>
    <id>env-igor-dev</id>
    <properties>
      <tomcatHost>localhost</tomcatHost>
      <tomcatPort>8091</tomcatPort>
      <tomcatManagerUser>tomcat</tomcatManagerUser>
      <tomcatManagerPassword>1</tomcatManagerPassword>
    </properties>
  </profile>
  <profile>
    <id>env-test</id>
    <properties>
      <tomcatHost>test.com</tomcatHost>
      <tomcatPort>8080</tomcatPort>
      <tomcatManagerUser>tom</tomcatManagerUser>
      <tomcatManagerPassword>fsKf2_3</tomcatManagerPassword>
    </properties>
  </profile>
 
  <!-- Профили, относящиеся к тому, что мы хотим собрать. При сборке можно указать 
       любую комбинацию этих профилей. -->
  <profile>
    <id>build-war1</id>
    <modules>
      <module>webapp-1</module>
    </modules>
  </profile>
  <profile>
    <id>build-war2</id>
    <modules>
      <module>webapp-2</module>
    </modules>
  </profile>
</profiles>
 
<build>
  <plugins>
    <plugin>
      <groupId>org.codehaus.cargo</groupId>
      <artifactId>cargo-maven2-plugin</artifactId>
      <configuration>
        <configuration>
          <properties>
            <cargo.hostname>${tomcatHost}</cargo.hostname>
            <cargo.protocol>http</cargo.protocol>
            <cargo.servlet.port>${tomcatPort}</cargo.servlet.port>
            <cargo.remote.username>${tomcatManagerUser}</cargo.remote.username>
            <cargo.remote.password>${tomcatManagerPassword}</cargo.remote.password>
          </properties>
          <type>runtime</type>
        </configuration>
        <container>
          <containerId>tomcat6x</containerId>
          <type>remote</type>
        </container>
        <!-- skip in parent pom and by default in all submodules -->
        <skip>true</skip>
      </configuration>
    </plugin>
  </plugins>
</build>

pom.xml одного из приложений:

<build>
  <plugins>
    <plugin>
      <artifactId>maven-war-plugin</artifactId>
      <configuration>
        <warName>war1</warName>
      </configuration>
    </plugin>
    <plugin>
      <groupId>org.codehaus.cargo</groupId>
      <artifactId>cargo-maven2-plugin</artifactId>
      <configuration>
        <deployables>
          <deployable>
            <location>webapp-1/target/war1.war</location>
          </deployable>
        </deployables>
        <skip>false</skip>
      </configuration>
    </plugin>
  </plugins>
</build>

pom.xml второго приложения составляется аналогично

Результат

Приложение собирается и деплоится одной командой
mvn clean package cargo:redeploy -P env-igor-dev,build-war1,build-war2

Update

Если у вас в war-приложении есть META-INF/context.xml, а в нём задан context path (например <Context antiJARLocking="true" path="/">), то cargo проигнорирует свойство deployable -> properties -> context и загрузит варник в ROOT.war. Поэтому если вам нужно, чтобы варник деплоился туда куда надо, настройте maven resources plugin с filtering=true чтобы path устанавливать в нужное вам значение.