2011-01-18 6 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を解析し、各jarファイルを開く - クラスを指定するマニフェストの要素を探します。それは次のようになります-IPluginインターフェースを実装するプラグインのパス。

は私が...

  • マイデプロイフォルダが現在のファンタジーであるトラブルを抱えていますいくつかのmaven/jarファイルの概念があります。それは存在しない。私はそれを存在させる知識がありません。現在、各サブプロジェクト(またはIntelliJで呼び出されているモジュール)に個別のJARファイルがあります
  • main-app.jarにsdkクラスを含める必要がありますか?
  • そうでない場合は、main-app.jarをどのように配備すればsdk.jarを知ることができますか。どこにsdk.jarを置くのですか?
  • plugin1 jarマニフェストファイルにカスタムフィールドを追加して、main-appのクラスパスをIPluginインターフェイスに関連付けるように指定する方法はありますか?

これまでのところ、私のpom.xmlファイルは非常にシンプルです。基本的にgroupID、artifactID、およびパッケージ化タイプ(JAR)とその依存関係を定義します。それで全部です。

現在、main-app(sansプラグイン)はIntelliJで正常にビルドされ、実行されますが、これはデプロイメントのパッケージ化にはまったく役に立ちません。

編集:

ただ、明確にするために... メインアプリとSDKが構築されており、開発中に配備されています。 plugin1は第三者によってplugins.folderに追加されます。サードパーティの開発者は、mavenを使用してplugin.jarマニフェストファイルでクラスパスをどのように指定するのですか?

答えて

1

main_appがウェブアプリケーションではなく、他のjarファイルに依存していて、distributeが必要な場合は、main_appを含むアセンブリ(.zipまたは.tar.gzファイルなど)を作成する方法があります.jarsと依存するjarファイル。 Maven Assembly Pluginこれを行うのに役立ちます。

あなたは正直Maven Jar Plugin

+0

これは私が探しているものだと思います...確かに、それはデスクトップアプリケーションであり、そのように配布されます... – helifreak

0

私はあなたの質問を理解していないかもしれません。しかし、あなたが達成しようとしているものは簡単です。あなたのメインアプリは他の2つのモジュールに依存しています。したがって、子モジュールを参照する主なアプリケーションプロジェクトに依存関係タグを追加するだけです。 (私は範囲を空のままにします)。

あなたのpomは、このようなプラグインモジュールの読み取りを言います。

<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 clean installでビルドする必要があります。

+0

あなたがmvn installを実行すると、あなたのjarがあなたのローカル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 ... 

アン、この時点では、あなたは論理的にそれを明確にどこにすべて残して、すべての様々な構成要素の部分を分離しました論理グループにパッケージ化されています。 (今、/ 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> 

この世界で聖なる権利のすべてを愛するために、でない場合 jar出力に関連するモジュールのいずれかにすべてをパッケージ化しようとします。これは間違っており、これを行うすべての人はシャントです。

私は冗談です。

しかし、真剣に:パッケージ化プロセスを別のモジュール、ここではsrc/app/deploymentモジュールに分解して、ビルドの他の成果物をパッケージ化します。その後、それは本当に唯一のシステム内の他のコンポーネントとの依存関係を持っている、とのようなものを見ることができます:あなたは1つのコヒーレント全体にすべてをパッケージ化するために(ここでは、image.xml)アセンブリ・ディスクリプタファイルを使用することができ、その後

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

、そのよう:

<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%を取得します裸の骨です。

残念ながら、私はこれを行うたくさんの、そしてこのプラクティスに従うと、実際には、特に後で数ヶ月後に戻ってくる必要があります。