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.



assembly plugin - format=zip - Zip Dosyası Oluşturma

Giriş
<format>
Her zaman zip değeri atanır

<fileSet> 
zip içine girecek kendi dosyalarım belirtilir. 

<dependencySet>
Zip içine girecek bağımlılıklarım belirtilir. 

<directory> 
Eklenecek şeyin projede nerede olduğu belirtilir.

<outputDirectory>
Zip içindeki hedef dizin belirtilir

<includes> 
Hem <fileSet> hem de <dependencySet> için kullanılabilir. Kaynak dosya belirtilir. Gerekirse wildcard kullanılabilir.

<descriptor>
Normalde kullanılacak descriptor dosya ismi assembly.xml şeklindedir. Farklı bir dosya ismi kullanmak istiyorsak bu tag ile belirtiriz

Örnek
Şöyle yaparız. Burada XML dosyası belirtiliyor.
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <executions>
    <execution>
      <id>assemblies</id>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <descriptors>
      <descriptor>../src/main/assembly/bin-assembly.xml</descriptor>
    </descriptors>
  </configuration>
</plugin>
xml şöyledir
- format olarak zip veriliyor
- fileSet ile zip dosyasında dahil edilecek dizin belirtiliyor
<assembly
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
 xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0
                     http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>bin</id>
<formats>
    <format>zip</format>
</formats>
<fileSets>
  <fileSet>
    <directory>../src/main/assembly/include</directory>
    <outputDirectory>/</outputDirectory>
  </fileSet>
</fileSets>
<dependencySets>
  <dependencySet>
    <outputDirectory>lib</outputDirectory>
  </dependencySet>
</dependencySets>
Örnek
Şöyle yaparız. target dizinindeki jar çıktısı ve projenin dizinindeki bat dosyaları birlikte zipleniyorlar. 
<directory> ile dosyanın nerede olduğu belirtiliyor.
<outputDirectory/> ile zip dosyasındaki yerleri belirtiliyor. 
<assembly>
  <formats>
    <format>zip</format>
  </formats>
  <fileSets>

    <fileSet>
      <directory>${targetDir}<directory>
      <outputDirectory/>
      <includes>
        <include>${artifactId}-${version}.jar</include>
      </includes>
    </fileSet>

    <fileSet>
      <outputDirectory/>
      <includes>
        <include>**/*bat</include>
      </includes>
    </fileSet>

  </fileSets>
</assembly>



Local Snapshot Kullanmak

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