You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by cl...@apache.org on 2022/08/01 19:13:08 UTC

[activemq-artemis] branch main updated: ARTEMIS-3914 Document client classpath automated

This is an automated email from the ASF dual-hosted git repository.

clebertsuconic pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git


The following commit(s) were added to refs/heads/main by this push:
     new 0cd203c32d ARTEMIS-3914 Document client classpath automated
0cd203c32d is described below

commit 0cd203c32de2c7913c46764dbf319510f3723b60
Author: Clebert Suconic <cl...@apache.org>
AuthorDate: Fri Jul 29 15:53:30 2022 -0400

    ARTEMIS-3914 Document client classpath automated
---
 artemis-maven-plugin/pom.xml                       |   8 +-
 .../artemis/maven/ArtemisAbstractPlugin.java       |  15 +-
 .../artemis/maven/ArtemisDependencyDocPlugin.java  | 257 +++++++++++++++++++++
 artemis-website/pom.xml                            |  79 +++++++
 docs/user-manual/en/SUMMARY.md                     |   2 +
 docs/user-manual/en/client-classpath-jakarta.md    |   1 +
 docs/user-manual/en/client-classpath-jms.md        |   1 +
 docs/user-manual/en/client-classpath.md            |  56 ++++-
 8 files changed, 408 insertions(+), 11 deletions(-)

diff --git a/artemis-maven-plugin/pom.xml b/artemis-maven-plugin/pom.xml
index 259cc0a3de..b54f32b9d9 100644
--- a/artemis-maven-plugin/pom.xml
+++ b/artemis-maven-plugin/pom.xml
@@ -40,17 +40,17 @@
       <dependency>
          <groupId>org.apache.maven</groupId>
          <artifactId>maven-artifact</artifactId>
-         <version>3.8.2</version>
+         <version>3.8.5</version>
       </dependency>
       <dependency>
          <groupId>org.apache.maven</groupId>
          <artifactId>maven-project</artifactId>
-         <version>2.0.8</version>
+         <version>2.2.1</version>
       </dependency>
       <dependency>
          <groupId>org.eclipse.aether</groupId>
          <artifactId>aether-api</artifactId>
-         <version>1.0.2.v20150114</version>
+         <version>1.1.0</version>
       </dependency>
       <dependency>
          <groupId>org.apache.activemq</groupId>
@@ -75,7 +75,7 @@
       <dependency>
          <groupId>org.apache.maven.plugin-tools</groupId>
          <artifactId>maven-plugin-annotations</artifactId>
-         <version>3.4</version>
+         <version>3.6.4</version>
          <scope>provided</scope>
       </dependency>
    </dependencies>
diff --git a/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ArtemisAbstractPlugin.java b/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ArtemisAbstractPlugin.java
index 6668ff1a45..37803612e9 100644
--- a/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ArtemisAbstractPlugin.java
+++ b/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ArtemisAbstractPlugin.java
@@ -102,7 +102,13 @@ public abstract class ArtemisAbstractPlugin extends AbstractMojo {
       return artifact;
    }
 
-   protected File resolveArtifact(Artifact artifact) throws MojoExecutionException, DependencyCollectionException {
+   protected File resolveArtifactFile(Artifact artifact) throws MojoExecutionException, DependencyCollectionException {
+      ArtifactResult result = resolveArtifact(artifact);
+
+      return result.getArtifact().getFile();
+   }
+
+   protected ArtifactResult resolveArtifact(Artifact artifact) throws MojoExecutionException {
       ArtifactRequest request = new ArtifactRequest();
       request.setArtifact(artifact);
       request.setRepositories(remoteRepos);
@@ -113,8 +119,7 @@ public abstract class ArtemisAbstractPlugin extends AbstractMojo {
       } catch (ArtifactResolutionException e) {
          throw new MojoExecutionException(e.getMessage(), e);
       }
-
-      return result.getArtifact().getFile();
+      return result;
    }
 
    protected List<Artifact> explodeDependencies(Artifact artifact) throws DependencyCollectionException {
@@ -164,7 +169,7 @@ public abstract class ArtemisAbstractPlugin extends AbstractMojo {
             List<Artifact> artifactsList = explodeDependencies(newArtifact(lib));
 
             for (Artifact artifact : artifactsList) {
-               File artifactFile = resolveArtifact(artifact);
+               File artifactFile = resolveArtifactFile(artifact);
                filesSet.add(artifactFile);
             }
          }
@@ -174,7 +179,7 @@ public abstract class ArtemisAbstractPlugin extends AbstractMojo {
          for (String lib : individualListParameter) {
             Artifact artifact = newArtifact(lib);
             getLog().debug("Single dpendency resolved::" + artifact);
-            File artifactFile = resolveArtifact(artifact);
+            File artifactFile = resolveArtifactFile(artifact);
             filesSet.add(artifactFile);
          }
       }
diff --git a/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ArtemisDependencyDocPlugin.java b/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ArtemisDependencyDocPlugin.java
new file mode 100644
index 0000000000..2dc5b869d3
--- /dev/null
+++ b/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ArtemisDependencyDocPlugin.java
@@ -0,0 +1,257 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.maven;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.project.MavenProject;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.resolution.ArtifactResult;
+
+/** The following substitutions are made for each line
+ * X{group} with the groupID
+ * X{artifact} with the artifactID
+ * X{version} with the version
+ * X{classifier} with the classifier of the component
+ * X{package} a combination of the maven group:artifact:classifier
+ * X{url} with the url
+ * X{file} with the fileName
+ * X{fileMD} with the fileName on a LINK with MD style
+ * X{URI} with the URI
+ * X{detail} with the detail provided in the config */
+@Mojo(name = "dependency-doc", defaultPhase = LifecyclePhase.VERIFY)
+public class ArtemisDependencyDocPlugin extends ArtemisAbstractPlugin {
+
+   @Parameter
+   String name;
+
+   /**
+    * The plugin descriptor
+    */
+   private PluginDescriptor descriptor;
+
+   @Parameter
+   private String[] groupOrder;
+
+   @Parameter(defaultValue = "https://repo.maven.apache.org/maven2")
+   private String defaultRepo = "https://repo.maven.apache.org/maven2";
+
+   @Parameter
+   private String header;
+
+   @Parameter
+   private String lib;
+
+   @Parameter
+   private String line;
+
+   @Parameter
+   private String footer;
+
+   @Parameter
+   private String[] detailKey;
+
+   @Parameter String[] detailValue;
+
+   @Parameter
+   private String[] extraRepositories;
+
+   @Parameter
+   private String file;
+
+   private MavenProject project;
+
+   @Override
+   protected boolean isIgnore() {
+      return false;
+   }
+
+
+   private String applyFilters(String content, Map<String, String> filters) throws IOException {
+
+      if (filters != null) {
+         for (Map.Entry<String, String> entry : filters.entrySet()) {
+            try {
+               content = replace(content, entry.getKey(), entry.getValue());
+            } catch (Throwable e) {
+               System.out.println("Error on " + entry.getKey());
+               e.printStackTrace();
+            }
+         }
+      }
+      return content;
+   }
+
+
+   private String replace(String content, String key, String value) {
+      return content.replaceAll(Pattern.quote(key), Matcher.quoteReplacement(value));
+   }
+
+   private String getPackageName(org.eclipse.aether.artifact.Artifact artifact) {
+      return artifact.getGroupId() + ":" + artifact.getArtifactId() + (artifact.getClassifier() != null && !artifact.getClassifier().equals("") ? ":" + artifact.getClassifier() : "");
+   }
+
+   private String getGroupOrder(String group) {
+      if (groupOrder == null) {
+         groupOrder = new String[] {"org.apache.activemq"};
+      }
+
+      int i = 0;
+      for (; i < groupOrder.length; i++) {
+         if (group.equals(groupOrder[i])) {
+            return Integer.toString(i);
+         }
+      }
+      return Integer.toString(i);
+   }
+
+   @Override
+   protected void doExecute() {
+
+      HashMap<String, String> keys = new HashMap<>();
+
+      if (detailKey != null) {
+         if (detailValue == null) {
+            throw new IllegalStateException("you need to specify all detail parameters");
+         }
+
+         if (detailKey.length != detailValue.length) {
+            throw new IllegalStateException("Illegal argument size");
+         }
+
+         for (int i = 0; i < detailKey.length; i++) {
+            keys.put(detailKey[i], detailValue[i]);
+         }
+      }
+
+      if (file == null) {
+         throw new IllegalStateException("you must specify the file output");
+      }
+
+      if (line == null) {
+         throw new IllegalStateException("you must specify the line");
+      }
+
+
+      try {
+         File javaFile = new File(file);
+         javaFile.getParentFile().mkdirs();
+
+         PrintStream stream = new PrintStream(new BufferedOutputStream(new FileOutputStream(file)));
+
+         if (header != null) {
+            stream.println(header);
+         }
+
+         List<org.eclipse.aether.artifact.Artifact> artifacts = explodeDependencies(newArtifact(lib));
+
+         Collections.sort(artifacts, new Comparator<Artifact>() {
+            @Override
+            public int compare(Artifact o1, Artifact o2) {
+               String pref1 = getGroupOrder(o1.getGroupId());
+               String pref2 = getGroupOrder(o2.getGroupId());
+               return (pref1 + o1.getGroupId() + o1.getArtifactId()).compareTo(pref2 + o2.getGroupId() + o2.getArtifactId());
+            }
+         });
+
+         artifacts.forEach((art) -> {
+            try {
+
+               String detail = keys.get(art.getGroupId() + ":" + art.getArtifactId());
+               if (detail == null) {
+                  detail = "";
+               }
+
+               ArtifactResult result = resolveArtifact(art);
+
+               HashMap<String, String> filter = new HashMap<>();
+               filter.put("X{detail}", detail);
+               filter.put("X{group}", art.getGroupId());
+               filter.put("X{artifact}", art.getArtifactId());
+               filter.put("X{classifier}", result.getArtifact().getClassifier());
+               filter.put("X{package}", getPackageName(result.getArtifact()));
+               filter.put("X{file}", result.getArtifact().getFile().getName());
+               filter.put("X{version}", result.getArtifact().getVersion());
+
+               String uri = getURI(result);
+
+               filter.put("X{uri}", uri);
+
+               if (uri.equals("")) {
+                  filter.put("X{fileMD}", result.getArtifact().getFile().getName());
+               } else {
+                  filter.put("X{fileMD}", "[" + result.getArtifact().getFile().getName() + "](" + uri + ")");
+               }
+
+               String output = applyFilters(line, filter);
+
+               if (getLog().isDebugEnabled()) {
+                  filter.forEach((a, b) -> {
+                     getLog().debug("filter.put(" + a + ", " + b + ")");
+                  });
+                  getLog().debug(output);
+               }
+
+
+               stream.println(output);
+
+            } catch (Exception e) {
+               throw new RuntimeException(e.getMessage(), e);
+            }
+         });
+         if (footer != null) {
+            stream.println(footer);
+         }
+         stream.close();
+      } catch (Throwable e) {
+         getLog().error(e.getMessage(), e);
+      }
+   }
+
+   private String getURI(ArtifactResult result) {
+      Artifact art = result.getArtifact();
+      String uri = "";
+      if (result.getRepository() instanceof RemoteRepository) {
+         RemoteRepository remoteRepository = (RemoteRepository) result.getRepository();
+         uri = remoteRepository.getUrl();
+      } else {
+         uri = defaultRepo;
+      }
+
+      return uri + "/" +
+            art.getGroupId().replace('.', '/') + "/" +
+            art.getArtifactId() + "/" +
+            art.getVersion();
+   }
+
+}
diff --git a/artemis-website/pom.xml b/artemis-website/pom.xml
index bf4a099b92..893199cba1 100644
--- a/artemis-website/pom.xml
+++ b/artemis-website/pom.xml
@@ -199,6 +199,85 @@
                     <skip>${skipWebsiteDocGeneration}</skip>
                   </configuration>
                </plugin>
+               <plugin>
+                  <groupId>org.apache.activemq</groupId>
+                  <artifactId>artemis-maven-plugin</artifactId>
+                  <version>${project.version}</version>
+                  <executions>
+                     <execution>
+                        <id>doc-jms-client</id>
+                        <phase>generate-sources</phase>
+                        <goals>
+                           <goal>dependency-doc</goal>
+                        </goals>
+                        <configuration>
+                           <file>${scratch-dir-user-manual}/client-classpath-jms.md</file>
+                           <groupOrder>
+                              <arg>org.apache.activemq</arg>
+                              <arg>jakarta.jms</arg>
+                              <arg>org.jgroups</arg>
+                              <arg>io.netty</arg>
+                           </groupOrder>
+                           <header>#Artemis JMS Client Dependencies
+
+File | observation | package
+---|---|---</header>
+                           <line>X{fileMD}| X{detail} |X{package} </line>
+                           <detailKey>
+                              <arg>io.netty:netty-transport-native-epoll</arg>
+                              <arg>io.netty:netty-transport-classes-epoll</arg>
+                              <arg>io.netty:netty-transport-native-kqueue</arg>
+                              <arg>io.netty:netty-transport-classes-kqueue</arg>
+                              <arg>org.jgroups:jgroups</arg>
+                           </detailKey>
+                           <detailValue>
+                              <arg>only if you want epoll on Linux</arg>
+                              <arg>only if you want epoll on Linux</arg>
+                              <arg>only if you want kqueue on MacOS</arg>
+                              <arg>only if you want kqueue on MacOS</arg>
+                              <arg>only if you want JGroups discovery from the clients</arg>
+                           </detailValue>
+                           <lib>org.apache.activemq:artemis-jms-client:${project.version}</lib>
+                        </configuration>
+                     </execution>
+                     <execution>
+                        <id>doc-jakarta-client</id>
+                        <phase>generate-sources</phase>
+                        <goals>
+                           <goal>dependency-doc</goal>
+                        </goals>
+                        <configuration>
+                           <file>${scratch-dir-user-manual}/client-classpath-jakarta.md</file>
+                           <groupOrder>
+                              <arg>org.apache.activemq</arg>
+                              <arg>jakarta.jms</arg>
+                              <arg>org.jgroups</arg>
+                              <arg>io.netty</arg>
+                           </groupOrder>
+                           <header>#Artemis Jakarta Client Dependencies
+File | observation | package
+---|---|---</header>
+                           <line>X{fileMD}| X{detail} |X{package} </line>
+                           <detailKey>
+                              <arg>io.netty:netty-transport-native-epoll</arg>
+                              <arg>io.netty:netty-transport-classes-epoll</arg>
+                              <arg>io.netty:netty-transport-native-kqueue</arg>
+                              <arg>io.netty:netty-transport-classes-kqueue</arg>
+                              <arg>org.jgroups:jgroups</arg>
+                           </detailKey>
+                           <detailValue>
+                              <arg>only if you want epoll on Linux</arg>
+                              <arg>only if you want epoll on Linux</arg>
+                              <arg>only if you want kqueue on MacOS</arg>
+                              <arg>only if you want kqueue on MacOS</arg>
+                              <arg>only if you want JGroups discovery from the clients</arg>
+                           </detailValue>
+                           <lib>org.apache.activemq:artemis-jakarta-client:${project.version}</lib>
+                        </configuration>
+                     </execution>
+                  </executions>
+               </plugin>
+
                <plugin>
                   <artifactId>maven-antrun-plugin</artifactId>
                   <executions>
diff --git a/docs/user-manual/en/SUMMARY.md b/docs/user-manual/en/SUMMARY.md
index 0d0b1b6a38..ff5d3acfee 100644
--- a/docs/user-manual/en/SUMMARY.md
+++ b/docs/user-manual/en/SUMMARY.md
@@ -22,6 +22,8 @@
 * [Mapping JMS Concepts to the Core API](jms-core-mapping.md)
 * [Using JMS](using-jms.md)
 * [The Client Classpath](client-classpath.md)
+    * [JMS](client-classpath-jms.md)
+    * [Jakarta](client-classpath-jakarta.md)
 * [Examples](examples.md)
 * [Routing Messages With Wild Cards](wildcard-routing.md)
 * [Wildcard Syntax](wildcard-syntax.md)
diff --git a/docs/user-manual/en/client-classpath-jakarta.md b/docs/user-manual/en/client-classpath-jakarta.md
new file mode 100644
index 0000000000..db012341fd
--- /dev/null
+++ b/docs/user-manual/en/client-classpath-jakarta.md
@@ -0,0 +1 @@
+This file will be generated/replaced in compile time by artemis-website
\ No newline at end of file
diff --git a/docs/user-manual/en/client-classpath-jms.md b/docs/user-manual/en/client-classpath-jms.md
new file mode 100644
index 0000000000..db012341fd
--- /dev/null
+++ b/docs/user-manual/en/client-classpath-jms.md
@@ -0,0 +1 @@
+This file will be generated/replaced in compile time by artemis-website
\ No newline at end of file
diff --git a/docs/user-manual/en/client-classpath.md b/docs/user-manual/en/client-classpath.md
index b2820fed5e..7a446eb96f 100644
--- a/docs/user-manual/en/client-classpath.md
+++ b/docs/user-manual/en/client-classpath.md
@@ -10,7 +10,59 @@ Apache ActiveMQ Artemis requires just a single jar on the *client classpath*.
 > jars from different Apache ActiveMQ Artemis versions. Mixing and matching
 > different jar versions may cause subtle errors and failures to occur.
 
+
+## Maven Packages
+
+The best way to define a client dependency to your java application is through a maven dependency declaration.
+
+There are two packages you can choose from, org.apache.activemq:artemis-jms-client or org.apache.activemq:artemis-jakarta-client for both JMS and Jakarta APIs.
+
+Say you define artemis-version as '{{ config.version }}':
+
+For JMS:
+```xml
+...
+<dependency>
+   <groupId>org.apache.activemq</groupId>
+   <artifactId>artemis-jms-client</artifactId>
+   <version>${artemis-version}</version>
+</dependency>
+...
+```
+
+For Jakarta:
+```xml
+...
+<dependency>
+   <groupId>org.apache.activemq</groupId>
+   <artifactId>artemis-jakarta-client</artifactId>
+   <version>${artemis-version}</version>
+</dependency>
+...
+```
+
+## All clients
+
+Even though it is highly recommend using maven, in case this is not a possibility the all inclusive jars could be used. 
+
+These jars will be available under ./lib/client on the main distribution:
+
+- artemis-jakarta-client-all-{{ config.version }}.jar
+- artemis-jms-client-all-{{ config.version }}.jar
+
 Whether you are using JMS or just the Core API simply add the
 `artemis-jms-client-all.jar` from the `lib/client` directory to your client
-classpath. This is a "shaded" jar that contains all the Artemis code plus
-dependencies (e.g.  JMS spec, Netty, etc.).
+classpath. 
+
+
+**Warning:**These jars will include all the [client's dependencies](client-classpath-jms.md). Be careful with mixing other jars in your application as they may clash with other.
+
+
+## Individual dependencies
+
+You may also choose to use the jars individually as they are all included under ./lib on the main distribution.
+
+For more information:
+
+- [client jms dependencies](client-classpath-jms.md )
+- [client jakarta dependencies](client-classpath-jakarta.md)