1 Aralık 2023 Cuma

Local Snapshot Kullanmak

Örnek
Şöyle yaparız
<repository>
  <id>snapshot-repository</id>
  <name>Maven2 Snapshot Repository</name>
  <url>https://oss.sonatype.org/content/repositories/snapshots</url>
  <snapshots>
    <enabled>false</enabled>
    </snapshots>
</repository>
Şöyle yaparız
mvn -o `-Dcheckstyle.skip install

3 Ekim 2023 Salı

surefire plugin - surefirebooter Process

surefirebooter Nedir ?
Açıklaması şöyle. Yani birim testleri çalıştıran uygulama
API and Facilities used by forked tests running in JVM sub-process.
surefirebooter Uygulamasını Nasıl Görebilirim ?
mvn clean install ile testleri koşmaya başlarız. surefire çalışınca jps komutu ile çalışan java uygulamalarına bakarız. surefirebooter-abc.jar diye bir process görürüz. 

Kaç Tane surefirebooter Çalışır ?
Kaç tane çalışacağını forkCount tag ile kontrol ediyoruz. Belirtilen sayı kadar kadar surefirebooter çalışıyor

Too many open files Hatası
Linux veya MacOs ile çalışıyorsak ulimit ile açılabilecek dosya için sınır koysak bile JVM çalışırken bu sınırı değiştiriyor. Bunu gösteren bir açıklama burada. Yani bir anlamda ulimit etkin değil. JVM kendi kendine bir üst sınır koyuyor ve MacOS için bu üst sınır değeri 10240.

Bunu değiştirmek için -XX:- MaxFDLimit seçeneği kullanılır

Bu seçeneği gösteren bir örnek burada

Ben de şöyle bir kod yazdım
public static void main(String[] args) throws Exception {
  List<InputStream> streams = new ArrayList<>();
  int index = 0;
  while (true) {
    FileInputStream fileInputStream = new FileInputStream("/dev/null");
    streams.add(fileInputStream);
    System.out.println("Index " + ++index);
  }
}
MacOS'ta eğer şöyle çalıştırırsam aldığım sonuç 10235
java scratch.java
Şimdi ulimit ile üst sınır koyalım
ulimit -n 2000
Tekrar MacOS'ta eğer şöyle çalıştırırsam aldığım sonuç 1995
java  -XX:- MaxFDLimit scratch.java
Benzer bir açıklama burada
The JVM on macOS has its own built-in max open files limit, set to 10240. This limit can be removed by passing the -XX:-MaxFDLimit option to the JVM.

However, if the built-in limit is removed, the JVM starts to use the soft limit as the absolute limit. Soft limits can be set very low, which makes the JVM option seemingly not working. This should be taken into consideration when using this JVM option.
maven ile çalıştırmak için şöyle yaparız
MAVEN_OPTS="$MAVEN_OPTS -XX:-MaxFDLimit"; export MAVEN_OPTS;  
Daha sonra şöyle yaparız
mvn test -Dtest=Foo 





19 Eylül 2023 Salı

wagon plugin

Örnek
Şöyle yaparız
<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>wagon-maven-plugin</artifactId>
  <version>2.0.2</version>
  <executions>
    <execution>
      <id>download-file-1</id>
      <phase>process-resources</phase>
      <goals>
        <goal>download-single</goal>
       </goals>
       <configuration>
         <url>https:/.../couchbase-kafka-connect-couchbase-4.1.11.zip</url>
         <toDir>${project.build.directory}/classes</toDir>
         </configuration>
         </execution>
       </executions>
</plugin>
Çalıştırmak için şöyle yaparız
mvn process-resources

17 Eylül 2023 Pazar

download plugin

Giriş
3 tane goal var
artifact
help
wget

wget Goal
Belirtilen dosyası indirir. Sadece <outputDirectory> ve <uri> bilgileri zorunlu. Çalıştırmak için şöyle yaparız
mvn download:wget
Eğer birden fazla wget varsa veya şöyle yaparız
mvn process-resources
Eğer logları görmek istersek şöyle yaparız
mvn download:wget -X
<cacheDirectory> Tag
İndirilen dosya <cacheDirectory> ile belirtilen yerde ön bellekte saklanır. Bu dizinin varsayılan yolu ${local-repo}/.cache/maven-download-plugin olarak. Ben kullanırken D:\Users\user\.m2\.cache\download-maven-plugin dizini altında önbellekte saklanan dosyaları gördüm

<retries> Tag
Varsayılan değer 2. Yani 2 defa indirme işlemini deniyor.

Örnek - Ortak Configuration
Şöyle yaparız. 1.7.2 bozuk
<plugin>
  <groupId>com.googlecode.maven-download-plugin</groupId>
  <artifactId>download-maven-plugin</artifactId>
  <version>1.6.8</version>
  <executions>
    <execution>
      <id>download-zip-file</id>
      <phase>process-resources</phase>
      <goals>
        <goal>wget</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <url>https://.../confluentinc-kafka-connect-datagen-0.6.0.zip</url>
    <unpack>false</unpack>
    <outputDirectory>${project.build.directory}/classes</outputDirectory>
    </configuration>
  </plugin>
</plugins>
process-resources aramasında wget ile dosya ${project.build.directory}/classes dizinine indirilir. Bu dizin aslında target/classes dizinine denk gelir.

Örnek - Birden Fazla Dosya İndirme
Şöyle yaparız
<plugin>
  <groupId>com.googlecode.maven-download-plugin</groupId>
  <artifactId>download-maven-plugin</artifactId>
  <version>1.6.8</version>
  <executions>
    <execution>
      <id>download-zip-file1</id>
      <goals>
        <goal>wget</goal>
      </goals>
      <configuration>
        <url>https://.../couchbase-kafka-connect-couchbase-4.1.11.zip</url>
        <unpack>false</unpack>
        <outputDirectory>${project.build.directory}/classes</outputDirectory>
      </configuration>
    </execution>
    <execution>
      <id>download-zip-file2</id>
      <goals>
        <goal>wget</goal>
      </goals>
      <configuration>
        <url>https://.../neo4j-kafka-connect-neo4j-2.0.1.zip</url>
        <unpack>false</unpack>
        <outputDirectory>${project.build.directory}/classes</outputDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>
wget  process-resources Safhasında Çalışır
mvn test ile çalıştırılan safhalar şöyle. Yani wget aslında test sahasından önce çalışıyor. Eğer bu uygun değilse başka bir safhayı yazmak gerekir.
validate                         validate the project is correct and all necessary information is available.
initialize                         initialize build state, e.g. set properties or create directories.
generate-sources                 generate any source code for inclusion in compilation.
process-sources         process the source code, for example to filter any values.
generate-resources         generate resources for inclusion in the package.
process-resources               copy and process the resources into the destination directory, ready for packaging.
compile                 compile the source code of the project.
process-classes         post-process the generated files from compilation, for example to do bytecode enhancement on Java classes.
generate-test-sources         generate any test source code for inclusion in compilation.
process-test-sources         process the test source code, for example to filter any values.
generate-test-resources create resources for testing.
process-test-resources copy and process the resources into the test destination directory.
test-compile                 compile the test source code into the test destination directory
process-test-classes         post-process the generated files from test compilation, for example to do bytecode enhancement on Java classes.
test




12 Eylül 2023 Salı

Predefined Properties

project
Açıklaması şöyle
${project.build.directory} 
results in the path to your "target" directory ${project.build.outputDirectory} results in the path to your "target/classes" directory

${project.name} 
refers to the name of the project

${project.version} 
refers to the version of the project

${project.groupId} 
refers to the groupId of the project

${project.build.finalName} 
refers to the final name of the file created when the built project is packaged

22 Ağustos 2023 Salı

Conflicting Transitive Dependency

Giriş
İstenilen transitive dependency sürümünü tanımlamak için kullanılabilir. Açıklaması şöyle
The point of dependencyManagement is to allow me to specify a version for transitive dependencies. 
Örnek
Şöyle yaparız
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>conflicting.group</groupId>
      <artifactId>TransitiveDependency</artifactId>
      <version>desired.version</version>
    </dependency>
  </dependencies>
</dependencyManagement>
Örnek - BOM
Şöyle yaparız. Burada Log4J2 için BOM kullanılıyor. Böylece tüm projedeki log4j sürümü değiştirilebiliyor.
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-bom</artifactId>
      <version>${log4j2.version}</version>
      <scope>import</scope>
      <type>pom</type>
    </dependency>
  </dependencies>
</dependencyManagement>

Örnek
Bir projede snakeyaml kütüphanesinin eski bir sürümü  transitive dependency olarak gelsin ama biz daha yeni bir sürüm kullanmak isteyelim. Şöyle yaparız
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.yaml</groupId>
      <artifactId>snakeyaml</artifactId>
      <version>1.32</version>
    </dependency>
  </dependencies>
</dependencyManagement>

13 Ağustos 2023 Pazar

Apache Ant

Giriş
Açıklaması şöyle
Ant is based on three main abstractions:

- A task is an atomic unit of work, e.g., javac to compile Java files, war to assemble a Web Archive, etc. Ant provides lots of tasks out-of-the-box but allows adding custom ones.
- A target is a list of tasks
- You can define dependencies between tasks, such as package depending on compile. In this regard, you can see Ant as a workflow execution engine.

31 Temmuz 2023 Pazartesi

25 Temmuz 2023 Salı

mvn komutu -pl seçeneği - Project List

Giriş
Multi-module projelerde kullanılır. "project list" anlamına gelir. Tüm projeleri değil sadece ismi belirtilen projeyi derler. Açıklaması şöyle.
-pl,--projects <arg> >> Comma-delimited list of specified reactor projects to build
  instead of all projects. A project can be specified by [groupId]:artifactId or by its
  relative path.
Örnek
Şöyle yaparız.
mvn package -pl sub_module
Örnek
Şöyle yaparız. Burada module ismi gateway ve spring-boot plugin'i tetikleniyor. 
mvn -pl gateway spring-boot:run 
-DskipTests
-Dspring-boot.run.arguments= — EUREKA_SERVER_ADDRESS=http://localhost:8761/eureka
Örnek - exlude
Şöyle yaparız. Burada - veya ! karakteri ile bazı modüllerin hariç bırakılması sağlanıyor
mvn install -DskipTests -pl -distribution,-extensions/hadoop-dist -f pom.xml

-amd ile Birlikte Kullanımı - also-make-dependents
Açıklaması şöyle
The -amd option stands for "also-make-dependents" and is used along with -pl to ensure that not only the specified modules are built but also the projects that depend on them.
Örnek
Bu modüle bağımlı olan diğerlerini de derlemek için şöyle yaparız.
mvn clean package -pl sub_module -amd
-am ile Birlikte Kullanımı - also-make
Açıklaması şöyle
The -am option stands for "also-make" and is used along with -pl to ensure that not only the specified modules are built but also their dependencies.
Örnek
Belirtilen modülün kullandığı diğer modülleri de derlemek istersek şöyle yaparız.
mvn clean package -pl sub_module -am

18 Temmuz 2023 Salı

dockerfile plugin

Giriş
Açıklaması şöyle
Spotify Dev team open-sourced many tools they are using among others dockerfile-maven-plugin as well.

The dockerfile-maven-plugin can create and publish a docker image based on your Dockerfile meanwhile running maven commands.

It allows you to configure the props based on your need. The usage doc can be found here. Authentication doc for publishing your app’s image to Google Cloud Container or your registry can be found here.
Örnek
Şöyle yaparız
<plugin>
  <groupId>com.spotify</groupId>
  <artifactId>dockerfile-maven-plugin</artifactId>
  <version>${dockerfile-maven-plugin.version}</version>
  <configuration>
    <repository>${docker.image.prefix}/${project.artifactId}</repository>
  </configuration>
  <executions>
    <execution>
      <id>default</id>
      <phase>install</phase>
      <goals>
        <goal>build</goal>
      </goals>
    </execution>
  </executions>
</plugin>
Docker dosyası için şöyle yaparız.  maven install komutu ile önce jar yapılandırılıyor. En son olarak ta Docker dosyası çalıştırılıyor
FROM openjdk:17-alpine as builder

WORKDIR application

ARG JAR_FILE=target/*.jar

COPY ${JAR_FILE} application.jar
RUN java -Djarmode=layertools -jar application.jar extract

FROM openjdk:17-alpine
WORKDIR application
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/application/ ./
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]
mvn deploy ile de Docker image Docker deposuna gönderilir

17 Temmuz 2023 Pazartesi

shade plugin - relocation Kullanımı

Giriş
Bazen bir kütüphane ile gelen 3. taraf bağımlılıklar ile kendi projem arasında uyumsuzluk olur.  

1. relocation Alanı
relocation ve shadedPattern genelde birlikte kullanılır

Örnek
Şöyle yaparız. Burada org.apache.calcite kodları başka bir dizinine toplanır
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <configuration>
    <shadedArtifactAttached>false</shadedArtifactAttached>
    <relocations>
      <relocation>
        <pattern>org.apache.calcite</pattern>
        <shadedPattern>${relocation.root}.org.apache.calcite</shadedPattern>
      </relocation>
    </relocations>
  </configuration>
</plugin>
Örnek
Şöyle yaparız
- Burada joda-time ve com.amazonaws kütüphanelerini dahil eden bir fat jar üretiliyor. 
- Ayrıca org.joda paketleri com.amazonaws.thirdparty.joda altına taşınıyor.
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <version>2.4.3</version>
  <configuration>
    <artifactSet>
      <includes>
        <include>joda-time:joda-time</include>
        <include>com.amazonaws:*</include>
      </includes>
    </artifactSet>
    <relocations>
      <relocation>
        <pattern>org.joda</pattern>
        <shadedPattern>com.amazonaws.thirdparty.joda</shadedPattern>
      </relocation>
    </relocations>
  </configuration>
</plugin>
Örnek
Şöyle yaparız
<plugin>
  <artifactId>maven-shade-plugin</artifactId>
  <configuration>

    <!-- Cancel the relocation of jackson-core defined in parent pom.
    <relocations combine.self="override">
    </relocations>
  </configuration>
</plugin>
veya şöyle yaparız
<plugin>
  <artifactId>maven-shade-plugin</artifactId>
  <configuration>

    <!-- Cancel the relocation of jackson-core defined in hazelcast-parent pom.
    <relocations combine.self="override">
      <relocation>
        <pattern>com.fasterxml.jackson.core</pattern>
        <shadedPattern>com.fasterxml.jackson.core</shadedPattern>
      </relocation>
    </relocations>
  </configuration>
</plugin>
2. Sadece shadedPattern Alanı
Açıklaması şöyle. Kendi kodlarım ve dependency olarak gelen kütüphaneler shade isimli bir dizine toplanır. İstenirse bu dizine yeni bir isim verilebilir
The "shadedPattern" is a configuration option in the Maven Shade Plugin that specifies the pattern for renaming the classes and resources in the shaded JAR file.

When you use the Maven Shade Plugin to create a shaded JAR, it merges all the dependencies of your project into a single JAR file. During the shading process, the plugin renames the classes and resources from the original JAR files to avoid conflicts with other libraries in the classpath.

The shadedPattern option allows you to specify the pattern for the renamed classes and resources in the shaded JAR. By default, the pattern is "shade/[class]", which means that all classes and resources will be moved to a "shade" directory in the JAR file.

You can customize the shadedPattern option to change the directory structure or add prefixes or suffixes to the renamed classes and resources. For example, you could use the pattern "myapp/[artifactId]-[version]/[class]" to create a directory structure that includes the name and version of your project.
Örnek
Şöyle yaparız. Burada kendi kodlarım da dahil olmak üzere her şey myapp/my-app-1.0.0/ dizinine toplanır
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <version>3.2.4</version>
  <configuration>
    <shadedPattern>myapp/[artifactId]-[version]/[class]</shadedPattern>
  </configuration>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>shade</goal>
      </goals>
    </execution>
  </executions>
</plugin>

15 Haziran 2023 Perşembe

jacoco CLI Komut Satırından Çalıştırmak

dump seçeneği
Şöyle yaparız. Burada sırayla her POD üzerindeki JaCoCo agent'a bağlanıyor ve dump seçeneği ile dosyayı alıyor. Daha sonra merge seçeneği ile dosyaları birleştiriyor
#!/usr/bin/env bash

set -e -u -o pipefail

if [ "${#}" -lt 4 ]; then
  echo "Usage: ${0} <path-to-jacococli.jar> <kubernetes-context> <kubernetes-namespace> <kubernetes-pod-selector>"
  echo "For selector syntax, see https://kubernetes.io/docs/concepts/overview/working-with-objects/labels."
  exit 1
fi

JACOCO_CLI_LOCAL="$(realpath "${1}")"
CONTEXT="${2}"
NAMESPACE="${3}"
POD_SELECTOR="${4}"

# All resources are stored in a temporary directory.
TMP_DIR='/tmp/jacoco-export'
mkdir -p "${TMP_DIR}"
pushd "${TMP_DIR}"

# Fetch coverage data from all pods.
kubectl get pods \
  --context="${CONTEXT}" \
  --namespace="${NAMESPACE}" \
  --selector="${POD_SELECTOR}" \
  --no-headers \
  -o custom-columns=":metadata.name" \
  | while read POD; do
    # One pod at a time, open a tunnel, connect to the JaCoCo agent to fetch
    # the coverage data and close the tunnel again.
    echo $CONTEXT - $POD
    (
      kubectl port-forward \
        --context="${CONTEXT}" \
        --namespace "${NAMESPACE}" \
        "${POD}" \
        "6300:6300" &
      trap "kill ${!}" ERR EXIT HUP INT TERM
      java -jar "${JACOCO_CLI_LOCAL}" dump --destfile "jacoco-${POD}.exec"
    )
  done

# Merge the coverage data into a single file.
java -jar "${JACOCO_CLI_LOCAL}" merge --destfile jacoco.exec jacoco-*.exec
popd
report seçeneği
Örnek
Dosyayı HTML olarak formatlamak için şöyle yaparız
java -jar jacococli.jar report jacoco.exec [options]
Örnek
Şöyle yaparız.
#!/usr/bin/env bash

set -e -u -o pipefail

if [[ "${#}" -lt 2 ]]; then
  echo "Usage: ${0} <path-to-jacococli.jar> [--sourcefiles-matcher=<string>] [ --classfiles-miles-matcher<string>] <source-roots>..."
  exit 1
fi

JACOCO_CLI_LOCAL="$(realpath "${1}")"
shift
SOURCEFILES_MATCHER='*/src/main/java'
CLASSFILES_MATCHER='*/target/classes'

while [ "${#}" -gt 0 ]; do
  case "${1}" in
  --sourcefiles-matcher)
    shift
    SOURCEFILES_MATCHER="${1}"
    ;;
  --classfiles-matcher)
    shift
    CLASSFILES_MATCHER="${1}"
    ;;
  *)
    break
    ;;
  esac
done

if [[ "${#}" -ne 1 ]]; then
  echo "No source roots passed."
  exit 1
fi


pushd /tmp/jacoco-export

# Generate an HTML report based on the collected data. Note that this command
# assumes that the associated source code has been compiled (i.e. that the
# `target/classes` directories are present and populated).
java -jar "${JACOCO_CLI_LOCAL}" report jacoco.exec --html report \
  $(find "${@:1}" -path "${CLASSFILES_MATCHER}" | sed 's/^/--classfiles /') \
  $(find "${@:1}" -path "${SOURCEFILES_MATCHER}" | sed 's/^/--sourcefiles /')

popd

jacoco Agent'ı Komut Satırından Çalıştırmak

Giriş
Agent jar dosyasını GitHub veya Maven Central sayfasından  indiririz
CLI jar dosyasını GitHub sayfasından indiririz

Örnek
Şöyle yaparız. Burada jacoco.exec dosyası üretilir
java -jar myApp.jar -javaagent:/some/path/jacocoagent.jar
Dosyayı HTML olarak formatlamak için şöyle yaparız
java -jar jacococli.jar report jacoco.exec [options]
destfile seçeneği
Örnek
Şöyle yaparız
version: '3.7'

services:
  contract-first-service:
    image: ${SERVICE_GROUP}/${SERVICE_NAME}:${SERVICE_TAG}
    ports:
      - 4000:4000
    volumes:
      - type: bind
        source: ./build/jacoco
        target: /jacoco
    environment:
      - JAVA_TOOL_OPTIONS=-javaagent:/jacoco/org.jacoco.agent-runtime.jar=destfile=/jacoco/componentTest.exec
      - SPRING_PROFILE=${SPRING_PROFILE}
Açıklaması şöyle
1. we bind the build/jacoco folder into the container at the /jacoco location. This means, if we place the Jacoco agent in the build/jacoco location, we can access it when we start the application. Also, is we write the coverage report to this location, we will have access to it outside of the container.

2. we override the JAVA_TOOL_OPTIONS to attach the Jacoco agent to the applications JVM, and output the coverage report to /jacoco/componentTest.exec. This means the coverage report, due to the volume binding in step 1, will end up in build/jacoco when the test stops.
output seçeneği
Şöyle yaparız
javaagent:/path/to/jacocoagent.jar=includes=tech.picnic.*,output=tcpserver,address=*
Açıklaması şöyle. Burada JaCoCo bir TCP sunucusu başlatıyor ve bağlananlara çıktıyı gönderiyor
This enables the JaCoCo Java agent and configures it to only instrument classes in our tech.picnic.* packages. .... We also configure JaCoCo to write to incoming TCP connections through tcpserver, which we will use to interact with the agent. Using the server, we can fetch the data at any time while the pod is alive.

Note: As we expose a server here, security is important. By default, the JaCoCo server listens on port 6300. By setting address=* we only allow connections from local addresses. We do not expose port 6300 in our containers and services. 

12 Haziran 2023 Pazartesi

findbugs plugin

Giriş
Açıklaması şöyle
The Maven FindBugs Plugin is a static analysis tool that detects potential bugs and issues in your Java code. It generates a report detailing any discovered problems, helping developers improve code quality.
Örnek
Şöyle yaparız
<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>findbugs-maven-plugin</artifactId>
  <version>3.0.5</version>
</plugin>

pmd plugin

Giriş
Açıklaması şöyle
The Maven PMD Plugin is another static analysis tool that detects coding issues, bad practices, and potential bugs. It provides a comprehensive report that helps developers identify areas for improvement.
Örnek
Şöyle yaparız
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-pmd-plugin</artifactId>
  <version>3.14.0</version>
</plugin>

1 Haziran 2023 Perşembe

assembly plugin - format=dir

Örnek
Projeyi yeni bir module ekleriz. İsmi packaging. Şöyle yaparız. app ve tools isimli iki tane module için de bağımlılığı var.
<?xml version="1.0" encoding="UTF-8"?>
<project ..."> <parent> <artifactId>root</artifactId> <groupId>org.everydaycodes</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <packaging>pom</packaging> <artifactId>packaging</artifactId> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.3.0</version> <executions> <execution> <id>build-package</id> <goals> <goal>single</goal> </goals> <phase>package</phase> <configuration> <descriptors> <descriptor>assembly.xml</descriptor> </descriptors> </configuration> </execution> </executions> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.everydaycodes</groupId> <artifactId>app</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.everydaycodes</groupId> <artifactId>tools</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </project>
assembly.xml şöyledir
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd"> <id>production-artifact</id> <formats> <format>dir</format> </formats> <dependencySets> <dependencySet> <useProjectArtifact>false</useProjectArtifact> <outputDirectory>shared</outputDirectory> <unpack>false</unpack> <excludes> <exclude>org.everydaycodes:app:*</exclude> <exclude>org.everydaycodes:tools:*</exclude> </excludes> </dependencySet> </dependencySets> <moduleSets> <moduleSet> <useAllReactorProjects>true</useAllReactorProjects> <includes> <include>org.everydaycodes:app:jar:</include> <include>org.everydaycodes:tools:jar:</include> </includes> <binaries> <unpack>false</unpack> <includeDependencies>false</includeDependencies> </binaries> </moduleSet> </moduleSets> </assembly>
<format> 
dir değeri kullanılır. Açıklaması şöyle
we set the format to dir. This means the resulting artifact will be a folder with JAR files in it. As an alternative, you can change that to jar and get one BIG jar file with all resources and dependencies
<dependencySet>
 Açıklaması şöyle. Kendi kodum olan dependency'lerimi kopyalamıyorum, çünkü bunlar moduleSet ile kopyalanacak
useProjectArtifact: We say that do not use the artifact from the module itself
outputDirectory: Put the dependencies in the folder named shared  
unpack: keep them as JAR files instead of unpacking 
exclude: exclude the app and tools from the dependency list.



Local Snapshot Kullanmak

Örnek Şöyle yaparız <repository> <id>snapshot-repository</id> <name>Maven2 Snapshot Repository</name> ...