2011-01-18 2 views
1

Итак, я бы назвал себя старшим разработчиком с небольшим опытом работы с java. Я работаю над небольшим проектом для домашних животных, который в основном представляет собой настольное приложение и sdk для плагинов, и набор плагинов, которые приложение загружает, пока они реализуют интерфейсы, определенные в sdk. Это выглядит примерно так:Вопросы для начинающих Maven - хотя и несколько сложная настройка проекта

Структура проекта

main-app 
|---pom.xml (depends on <sdk>) 
|---src 
    |---[com.etc…] 
|---target 
    |---main-app.jar (does this include sdk.jar?) 


sdk 
|---pom.xml 
|---src 
    |---[com.etc…] 
     |---IPlugin (public interface IPlugin) 
|---target 
    |---sdk.jar 

(sdk - defines the interface that plugins need to implement) 


plugins 
|---plugin1 
    |---pom.xml (depends on <sdk>) 
    |---src 
     |---[com.etc…] 
    |---target 
     |---plugin1.jar 

plugin1 is a plugin that implements IPlugin interface and has the following classpath 
<com.foo.plugin1> 

deploy 
|---app.folder 
    |---main-app.jar 
    |---sdk.jar 
    |---plugins.folder 
     |---plugin1.jar 


О применении при запуске системы main.app разбирает plugins.folder и открывает каждый файл фляги - ищет элемент в манифесте, который определяет класс -path плагина, который реализует интерфейс IPlugin.

Есть несколько концепций Maven/баночка у меня возникли проблемы с ...

  • Моя папка развертывания в настоящее время фантазии. Этого не существует. У меня нет знаний, чтобы он существовал. В настоящее время у меня есть отдельный файл JAR в каждом подпроекте (или в модуле, который вызывается в IntelliJ)
  • Включает ли в main-app.jar классы sdk?
  • Если нет, как мне развернуть main-app.jar, чтобы он знал о sdk.jar, и где я могу поместить sdk.jar?
  • Есть ли способ добавить настраиваемое поле в файл манифеста plugin1 jar, где я могу указать его путь к классу для основного приложения, чтобы связать его с интерфейсом IPlugin?

До сих пор мои файлы pom.xml были очень просты. Они в основном определяют идентификатор groupID, artifactID и тип упаковки (JAR), а также их зависимости. это все.

В настоящее время плагин main-app (sans plugins) успешно работает и работает в IntelliJ - но это не помогает мне с упаковкой развертывания.

Edit:

Просто чтобы быть ясно ... основного приложения и SDK построены и развернуты в процессе разработки. plugin1 добавляется третьей стороной в plugins.folder. Как сторонние разработчики определяют свой путь класса в файле манифеста plugin.jar с помощью maven?

ответ

1

Если main_app не является веб-приложением и зависит от других банок, и если вам нужно это сделать, то одним из способов сделать это было бы создание сборки (например, файл .zip или .tar.gz), который включает в себя main_app .jars и зависимые банки. Maven Assembly Plugin может помочь вам в этом.

Вы можете сделать манифеста настройки с помощью Maven Jar Plugin

+0

Я думаю, что это то, что я ищу ... действительно, это не веб-приложение - это настольное приложение и будет распространяться как таковое ... – helifreak

0

Возможно, я не понял ваш вопрос. Но похоже, что вы пытаетесь достичь, тривиально. Основное приложение зависит от двух других модулей. Поэтому вам просто нужно добавить тег зависимости в своем основном проекте приложения, ссылаясь на дочерние модули. (Я оставлю область пустым).

Допустим, ваш модуль для модуля плагинов читается следующим образом.

<groupId>om.foo.plugin1</groupId> 
<artifactId>plugin1</artifactId> 
<version>1.0</version> 

Просто добавьте соответствующий тег зависимостей в основной модуль.

<dependency> 
    <groupId>om.foo.plugin1</groupId> 
    <artifactId>plugin1</artifactId> 
    <version>1.0</version> 
</dependency> 

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

+0

Когда вы запустите mvn install, ваша банка будет установлена ​​в ваш локальный репозиторий maven и другие модули могут ссылаться на него. –

0

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

Во-первых, я хотел бы разделить свой код на несколько модулей, и положи его следующим образом:

pom.xml 
/src 
    /app 
     /app-name 
      pom.xml 
      /src ... 
     /app-name-sdk 
      pom.xml 
      /src ... 
     /deployment 
      pom.xml 
      /src 
       /assembly 
        image.xml 
       /main 
        /app-folder 
         /bin 
          startup-script.sh 
          startup-script.bat 
         /etc 
          config.conf 
          ... 
    /plugins 
     /plugin-A 
      pom.xml 
      /src ... 
     /plugin-B 
      pom.xml 
      /src ... 

An это точка, вы логически разделены все различные составные части, в результате чего ясно, где все , упаковывается в логические группы. (Теперь, когда я проверяю это снова, он не похож на папку vomit, так как теперь я могу хранить директории/doc и/bin на верхнем уровне и знать, что подкаталоги в/src описывают, что находится в каждом ассоциированном подмодуле.)

в этот момент верхний pom.xml уровень должен выглядеть примерно так:

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 

    <modelVersion>4.0.0</modelVersion> 

    <artifactId>app-name-parent</artifactId> 
    <groupId>com.mycompany.my-app</groupId> 
    <version>1.3.2-SNAPSHOT</version> 
    <packaging>pom</packaging> 

    <name>[Parent] My App</name> 

    <modules> 
     <!-- App --> 
     <module>src/app/app-name</module> 
     <module>src/app/my-app-sdk</module> 

     <!-- Plugins --> 
     <module>src/plugins/plugin-A</module> 
     <module>src/plugins/plugin-B</module> 

     <!-- Packaging --> 
     <module>src/app/distribution</module> 
    </modules> 

    <properties> 
     <!-- Useful properties to define here --> 
     <scm.revision>USER</scm.revision> 
     <compiler.debug>true</compiler.debug> 
     <compiler.optimize>false</compiler.optimize> 
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 

     <!-- If you're not going to version your plugins with the parent, 
      then you should pick out the specific version info here 
      for each plugin. That way, you could just update individual plugins. 
      If this is to be packaged up and shipped together, it's probably not necessary. 
     --> 
     <plugin-A.version>1.1</plugin-A.version> 
     <plugin-B.version>1.3</plugin-B.version> 
    </properties> 

    <build> 
     <pluginManagement> 
      <plugins> 
       <plugin> 
        <artifactId>maven-compiler-plugin</artifactId> 
        <version>2.3</version> 
        <configuration> 
         <source>1.6</source> 
         <target>1.6</target> 
         <debug>${compiler.debug}</debug> 
         <optimize>${compiler.optimize}</optimize> 
         <fork>true</fork> 
        </configuration> 
       </plugin> 
       <plugin> 
        <artifactId>maven-surefire-plugin</artifactId> 
        <version>2.5</version> 
        <configuration> 
         <includes> 
          <include>**/*Test.java</include> 
         </includes> 
        </configuration> 
       </plugin> 
      </plugins> 
     </pluginManagement> 
    </build> 

    <dependencyManagement> 
     <dependencies> 

      <!-- Test Dependencies --> 
      <dependency> 
       <groupId>junit</groupId> 
       <artifactId>junit</artifactId> 
       <version>4.3.1</version> 
       <scope>test</scope> 
      </dependency> 
     </dependencies> 
    </dependencyManagement> 

    <profiles> 
     <profile> 
      <id>release</id> 

      <properties> 
       <compiler.debug>false</compiler.debug> 
       <compiler.optimize>true</compiler.optimize> 
      </properties> 
     </profile> 

     <profile> 
      <id>ci-server</id> 

      <activation> 
       <property> 
        <name>env.SVN_REVISION</name> 
       </property> 
      </activation> 

      <properties> 
       <scm.revision>${env.SVN_REVISION}</scm.revision> 
      </properties> 
     </profile> 
    </profiles> 
</project> 

Тогда все из дочерних модулей требуется определить ссылку на родителя, например, так:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <parent> 
     <artifactId>app-name-parent</artifactId> 
     <groupId>com.mycompany.my-app</groupId> 
     <version>1.3.2-SNAPSHOT</version> 
     <relativePath>../../..</relativePath> 
    </parent> 

    <groupId>com.mycompany.my-app</groupId> 
    <artifactId>app-name</artifactId> 

    <name>[App] My App</name> 
    <description> 
     TODO 
    </description> 

    <dependencies> 
     <!-- System dependencies --> 
     <dependency> 
      <groupId>${project.parent.groupId}</groupId> 
      <artifactId>app-name-sdk</artifactId> 
      <version>${project.version}</version> 
     </dependency> 

     <!-- Test Dependencies --> 
     <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <scope>test</scope> 
     </dependency> 
    </dependencies> 
</project> 

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

Я шучу.

Но серьезно: вывести процесс упаковки в отдельный модуль, здесь модуль src/app/deployment для упаковки других артефактов сборки. Тогда он действительно только зависит от других компонентов в системе, и может выглядеть примерно так:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <parent> 
     <artifactId>app-name-parent</artifactId> 
     <groupId>com.mycompany.my-app</groupId> 
     <version>1.3.2-SNAPSHOT</version> 
     <relativePath>../../..</relativePath> 
    </parent> 

    <groupId>com.mycompany.my-app</groupId> 
    <artifactId>deployment</artifactId> 
    <packaging>pom</packaging> 

    <name>[App]  Deployment Image</name> 
    <description> 
     TODO 
    </description> 

    <build> 
     <plugins> 
      <plugin> 
       <artifactId>maven-assembly-plugin</artifactId> 
       <executions> 
        <execution> 
         <id>image</id> 
         <phase>package</phase> 
         <goals> 
          <goal>single</goal> 
         </goals> 
         <configuration> 
          <tarLongFileMode>gnu</tarLongFileMode> 
          <descriptors> 
           <descriptor>src/assembly/image.xml</descriptor> 
          </descriptors> 
         </configuration> 
        </execution> 
       </executions> 
      </plugin> 
     </plugins> 
    </build> 

    <dependencies> 
     <dependency> 
      <groupId>${project.parent.groupId}</groupId> 
      <artifactId>my-app</artifactId> 
      <version>${project.version}</version> 
     </dependency> 
     <dependency> 
      <!-- Notice the separate group namespace element 'plugins', for clarity --> 
      <groupId>${project.parent.groupId}.plugins</groupId> 
      <artifactId>plugin-A</artifactId><!-- Or project.version, depending... --> 
      <version>${plugin-A.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>${project.parent.groupId}.plugins</groupId> 
      <artifactId>plugin-B</artifactId> 
      <version>${plugin-B.version}</version><!-- Or project.version, depending... --> 
     </dependency> 
    </dependencies> 
</project> 

Затем вы можете использовать дескриптор файла сборки (здесь, image.xml), чтобы упаковать все в единое целое , например, так:

<assembly> 
    <id>image</id> 
    <formats> 
     <format>tar.gz</format> 
    </formats> 
    <includeBaseDirectory>false</includeBaseDirectory> 

    <dependencySets> 
     <!-- Everything --> 
     <dependencySet> 
      <outputDirectory>/app-folder/jars</outputDirectory> 
      <useProjectArtifact>false</useProjectArtifact> 
      <fileMode>0644</fileMode> 
      <directoryMode>0644</directoryMode> 
      <!-- This includes all transitive, <scope>compile</scope> dependencies --> 

      <includes> 
       <include>${project.parent.groupId}:*</include> 
      </includes> 
     </dependencySet> 
    </dependencySets> 

    <!-- Packaged scripts, config files, etc. --> 
    <fileSets> 
     <fileSet> 
      <outputDirectory>/app-folder/bin</outputDirectory> 
      <lineEnding>unix</lineEnding> 
      <fileMode>0755</fileMode> 
      <directoryMode>0744</directoryMode> 
      <filtered>false</filtered> 

      <directory>src/main/app-folder/bin</directory> 
      <includes> 
       <include>**/*</include> 
      </includes> 

      <!-- Some weird files are added here, for some reason --> 
      <excludes> 
       <exclude>*.*.formatted</exclude> 
      </excludes> 
     </fileSet> 
     <fileSet> 
      <outputDirectory>/app-folder/etc</outputDirectory> 
      <lineEnding>unix</lineEnding> 
      <fileMode>0640</fileMode> 
      <directoryMode>0744</directoryMode> 
      <filtered>true</filtered> 

      <directory>src/main/app-folder/etc</directory> 
      <includes> 
       <include>**/*</include> 
      </includes> 

      <!-- Some weird files are added here, for some reason --> 
      <excludes> 
       <exclude>*.*.formatted</exclude> 
      </excludes> 
     </fileSet> 
    </fileSets> 
</assembly> 

Вы можете получить много любителя с упаковкой, но это голые кости, что получает вас 90% пути там.

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

Смежные вопросы