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 @@
org.apache.maven
maven-artifact
- 3.8.2
+ 3.8.5
org.apache.maven
maven-project
- 2.0.8
+ 2.2.1
org.eclipse.aether
aether-api
- 1.0.2.v20150114
+ 1.1.0
org.apache.activemq
@@ -75,7 +75,7 @@
org.apache.maven.plugin-tools
maven-plugin-annotations
- 3.4
+ 3.6.4
provided
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 explodeDependencies(Artifact artifact) throws DependencyCollectionException {
@@ -164,7 +169,7 @@ public abstract class ArtemisAbstractPlugin extends AbstractMojo {
List 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 filters) throws IOException {
+
+ if (filters != null) {
+ for (Map.Entry 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 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 artifacts = explodeDependencies(newArtifact(lib));
+
+ Collections.sort(artifacts, new Comparator() {
+ @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 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 @@
${skipWebsiteDocGeneration}
+
+ org.apache.activemq
+ artemis-maven-plugin
+ ${project.version}
+
+
+ doc-jms-client
+ generate-sources
+
+ dependency-doc
+
+
+ ${scratch-dir-user-manual}/client-classpath-jms.md
+
+ org.apache.activemq
+ jakarta.jms
+ org.jgroups
+ io.netty
+
+ #Artemis JMS Client Dependencies
+
+File | observation | package
+---|---|---
+ X{fileMD}| X{detail} |X{package}
+
+ io.netty:netty-transport-native-epoll
+ io.netty:netty-transport-classes-epoll
+ io.netty:netty-transport-native-kqueue
+ io.netty:netty-transport-classes-kqueue
+ org.jgroups:jgroups
+
+
+ only if you want epoll on Linux
+ only if you want epoll on Linux
+ only if you want kqueue on MacOS
+ only if you want kqueue on MacOS
+ only if you want JGroups discovery from the clients
+
+ org.apache.activemq:artemis-jms-client:${project.version}
+
+
+
+ doc-jakarta-client
+ generate-sources
+
+ dependency-doc
+
+
+ ${scratch-dir-user-manual}/client-classpath-jakarta.md
+
+ org.apache.activemq
+ jakarta.jms
+ org.jgroups
+ io.netty
+
+ #Artemis Jakarta Client Dependencies
+File | observation | package
+---|---|---
+ X{fileMD}| X{detail} |X{package}
+
+ io.netty:netty-transport-native-epoll
+ io.netty:netty-transport-classes-epoll
+ io.netty:netty-transport-native-kqueue
+ io.netty:netty-transport-classes-kqueue
+ org.jgroups:jgroups
+
+
+ only if you want epoll on Linux
+ only if you want epoll on Linux
+ only if you want kqueue on MacOS
+ only if you want kqueue on MacOS
+ only if you want JGroups discovery from the clients
+
+ org.apache.activemq:artemis-jakarta-client:${project.version}
+
+
+
+
+
maven-antrun-plugin
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
+...
+
+ org.apache.activemq
+ artemis-jms-client
+ ${artemis-version}
+
+...
+```
+
+For Jakarta:
+```xml
+...
+
+ org.apache.activemq
+ artemis-jakarta-client
+ ${artemis-version}
+
+...
+```
+
+## 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)