Last active
February 21, 2025 20:17
-
-
Save RajaniCode/6b3e6f0f40ef85a095f979ec64b4e6ff to your computer and use it in GitHub Desktop.
Maven Scala
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ########################################################################################################################### | |
| # Maven # Scala | |
| ########################################################################################################################### | |
| *************************************************************************************************************************** | |
| % export JAVA_HOME="$HOME/Downloads/Software/OpenJDK/JDK23.0.2/jdk-23.0.2.jdk/Contents/Home" | |
| % export M2_HOME="$HOME/Downloads/Software/ApacheMaven/apache-maven-3.9.9" | |
| % export M2="$M2_HOME/bin" | |
| % export PATH=$PATH:"$M2:$JAVA_HOME/bin" | |
| [ | |
| % export MAVEN_OPTS="-Xms256m -Xmx512m --enable-preview" | |
| ] | |
| % export MAVEN_OPTS="-Xms256m -Xmx512m" | |
| # Or | |
| % export PATH="$HOME/Downloads/Software/OpenJDK/JDK23.0.2/jdk-23.0.2.jdk/Contents/Home/bin/:$HOME/Downloads/Software/ApacheMaven/apache-maven-3.9.9/bin/":$PATH | |
| % java --version | |
| % mvn --version | |
| *************************************************************************************************************************** | |
| 1. mvn archetype | |
| *************************************************************************************************************************** | |
| # Interactive # Choose archetype | |
| % mvn archetype:generate | |
| ... | |
| Choose archetype: | |
| ... | |
| 1308: remote -> dev.qinx:scala-archetype (An up-to-date Maven Archetype for Scala) | |
| ... | |
| Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 2217: 1308 | |
| Choose dev.qinx:scala-archetype version: | |
| 1: 0.0.1 | |
| 2: 1.0.0 | |
| 3: 1.0.1 | |
| 4: 1.0.2 | |
| Choose a number: 4: 4 | |
| Downloading from central: https://repo.maven.apache.org/maven2/dev/qinx/scala-archetype/1.0.2/scala-archetype-1.0.2.jar | |
| Downloaded from central: https://repo.maven.apache.org/maven2/dev/qinx/scala-archetype/1.0.2/scala-archetype-1.0.2.jar (6.9 kB at 14 kB/s) | |
| Define value for property 'groupId': com.commons.project | |
| Define value for property 'artifactId': sample | |
| Define value for property 'version' 1.0-SNAPSHOT: 1.0-SNAPSHOT | |
| Define value for property 'package' com.commons.project: com.commons.project | |
| Confirm properties configuration: | |
| groupId: com.commons.project | |
| artifactId: sample | |
| version: 1.0-SNAPSHOT | |
| package: com.commons.project | |
| Y: Y | |
| *************************************************************************************************************************** | |
| # Tree recursive directory listing # default # % tree | |
| *************************************************************************************************************************** | |
| . | |
| └── sample | |
| ├── pom.xml | |
| └── src | |
| ├── main | |
| │ └── scala | |
| │ └── com | |
| │ └── commons | |
| │ └── project | |
| │ └── HelloWorld.scala | |
| └── test | |
| └── scala | |
| └── SimpleTestSuite.scala | |
| 10 directories, 3 files | |
| *************************************************************************************************************************** | |
| # mvn archetype # default # % cat sample/pom.xml | |
| *************************************************************************************************************************** | |
| <?xml version="1.0" encoding="UTF-8"?> | |
| <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" | |
| 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> | |
| <groupId>com.commons.project</groupId> | |
| <artifactId>sample</artifactId> | |
| <version>1.0-SNAPSHOT</version> | |
| <packaging>jar</packaging> | |
| <name>My Project</name> | |
| <description>My wonderfull scala app</description> | |
| <url>https://github.com/</url> | |
| <!--======Uncomment if you need to deploy the project======--> | |
| <!--<scm>--> | |
| <!-- <connection></connection>--> | |
| <!-- <developerConnection></developerConnection>--> | |
| <!-- <url></url>--> | |
| <!--</scm>--> | |
| <!--<licenses>--> | |
| <!-- <license>--> | |
| <!-- <name>The Apache License, Version 2.0</name>--> | |
| <!-- <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>--> | |
| <!-- </license>--> | |
| <!--</licenses>--> | |
| <!--<developers>--> | |
| <!-- <developer>--> | |
| <!-- <id>id</id>--> | |
| <!-- <name>YOUR NAME</name>--> | |
| <!-- <email>EMAIL</email>--> | |
| <!-- </developer>--> | |
| <!--</developers>--> | |
| <repositories> | |
| <repository> | |
| <id>maven.apache.org</id> | |
| <url>https://repo.maven.apache.org/maven2</url> | |
| </repository> | |
| <repository> | |
| <id>ossrh-snapshots</id> | |
| <url>https://oss.sonatype.org/content/repositories/snapshots/</url> | |
| </repository> | |
| </repositories> | |
| <properties> | |
| <scala.version>2.12.10</scala.version> | |
| <scala.compat.version>2.12</scala.compat.version> | |
| <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |
| <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | |
| <project.timezone>UTC</project.timezone> | |
| <java.version>1.8</java.version> | |
| <scoverage.plugin.version>1.4.0</scoverage.plugin.version> | |
| <site.plugin.version>3.7.1</site.plugin.version> | |
| <scalatest.version>3.1.2</scalatest.version> | |
| <scalatest-maven-plugin>2.0.0</scalatest-maven-plugin> | |
| <scala.maven.plugin.version>4.4.0</scala.maven.plugin.version> | |
| <maven.compiler.plugin.version>3.8.1</maven.compiler.plugin.version> | |
| <maven.javadoc.plugin.version>3.2.0</maven.javadoc.plugin.version> | |
| <maven.source.plugin.version>3.2.1</maven.source.plugin.version> | |
| <maven.deploy.plugin.version>2.8.2</maven.deploy.plugin.version> | |
| <nexus.staging.maven.plugin.version>1.6.8</nexus.staging.maven.plugin.version> | |
| <maven.help.plugin.version>3.2.0</maven.help.plugin.version> | |
| <maven.gpg.plugin.version>1.6</maven.gpg.plugin.version> | |
| <maven.surefire.plugin.version>2.22.2</maven.surefire.plugin.version> | |
| </properties> | |
| <dependencies> | |
| <!--======SCALA======--> | |
| <dependency> | |
| <groupId>org.scala-lang</groupId> | |
| <artifactId>scala-library</artifactId> | |
| <version>${scala.version}</version> | |
| <scope>provided</scope> | |
| </dependency> | |
| <!--======SPARK PROJECT======--> | |
| <!--<dependency>--> | |
| <!-- <groupId>org.apache.spark</groupId>--> | |
| <!-- <artifactId>spark-core_${scala.compat.version}</artifactId>--> | |
| <!-- <version>${spark.version}</version>--> | |
| <!-- <scope>provided</scope>--> | |
| <!--</dependency>--> | |
| <!--<dependency>--> | |
| <!-- <groupId>org.apache.spark</groupId>--> | |
| <!-- <artifactId>spark-sql_${scala.compat.version}</artifactId>--> | |
| <!-- <version>${spark.version}</version>--> | |
| <!-- <scope>provided</scope>--> | |
| <!--</dependency>--> | |
| <!--<dependency>--> | |
| <!-- <groupId>org.apache.spark</groupId>--> | |
| <!-- <artifactId>spark-mllib_${scala.compat.version}</artifactId>--> | |
| <!-- <version>${spark.version}</version>--> | |
| <!-- <scope>provided</scope>--> | |
| <!--</dependency>--> | |
| <!--<dependency>--> | |
| <!-- <groupId>org.apache.spark</groupId>--> | |
| <!-- <artifactId>spark-hive_${scala.compat.version}</artifactId>--> | |
| <!-- <version>${spark.version}</version>--> | |
| <!-- <scope>provided</scope>--> | |
| <!--</dependency>--> | |
| <!--======TYPESAFE CONFIG======--> | |
| <!--<dependency>--> | |
| <!-- <groupId>com.typesafe</groupId>--> | |
| <!-- <artifactId>config</artifactId>--> | |
| <!-- <version>1.4.0</version>--> | |
| <!--</dependency>--> | |
| <!--======Test======--> | |
| <dependency> | |
| <groupId>org.scalatest</groupId> | |
| <artifactId>scalatest_${scala.compat.version}</artifactId> | |
| <version>${scalatest.version}</version> | |
| <scope>test</scope> | |
| </dependency> | |
| </dependencies> | |
| <build> | |
| <plugins> | |
| <plugin> | |
| <groupId>org.apache.maven.plugins</groupId> | |
| <artifactId>maven-compiler-plugin</artifactId> | |
| <version>${maven.compiler.plugin.version}</version> | |
| <configuration> | |
| <source>${java.version}</source> | |
| <target>${java.version}</target> | |
| </configuration> | |
| <executions> | |
| <execution> | |
| <id>default-compile</id> | |
| <phase>none</phase> | |
| </execution> | |
| </executions> | |
| </plugin> | |
| <plugin> | |
| <groupId>net.alchim31.maven</groupId> | |
| <artifactId>scala-maven-plugin</artifactId> | |
| <version>${scala.maven.plugin.version}</version> | |
| <configuration> | |
| <args> | |
| <arg>-unchecked</arg> | |
| <arg>-deprecation</arg> | |
| <arg>-feature</arg> | |
| <arg>-explaintypes</arg> | |
| <arg>-target:jvm-${java.version}</arg> | |
| </args> | |
| </configuration> | |
| <executions> | |
| <execution> | |
| <id>compile</id> | |
| <goals> | |
| <goal>compile</goal> | |
| </goals> | |
| </execution> | |
| <execution> | |
| <id>test-compile</id> | |
| <goals> | |
| <goal>testCompile</goal> | |
| </goals> | |
| </execution> | |
| <execution> | |
| <id>attach-javadocs</id> | |
| <goals> | |
| <goal>doc-jar</goal> | |
| </goals> | |
| </execution> | |
| <execution> | |
| <id>add-source</id> | |
| <goals> | |
| <goal>add-source</goal> | |
| </goals> | |
| </execution> | |
| </executions> | |
| </plugin> | |
| <plugin> | |
| <groupId>org.apache.maven.plugins</groupId> | |
| <artifactId>maven-javadoc-plugin</artifactId> | |
| <version>${maven.javadoc.plugin.version}</version> | |
| </plugin> | |
| <plugin> | |
| <groupId>org.apache.maven.plugins</groupId> | |
| <artifactId>maven-source-plugin</artifactId> | |
| <version>${maven.source.plugin.version}</version> | |
| <configuration> | |
| <outputDirectory>target</outputDirectory> | |
| <attach>true</attach> | |
| </configuration> | |
| <executions> | |
| <execution> | |
| <id>attach-sources</id> | |
| <goals> | |
| <goal>jar</goal> | |
| </goals> | |
| </execution> | |
| </executions> | |
| </plugin> | |
| <plugin> | |
| <groupId>org.apache.maven.plugins</groupId> | |
| <artifactId>maven-surefire-plugin</artifactId> | |
| <version>${maven.surefire.plugin.version}</version> | |
| <configuration> | |
| <skipTests>true</skipTests> | |
| </configuration> | |
| </plugin> | |
| <plugin> | |
| <groupId>org.scalatest</groupId> | |
| <artifactId>scalatest-maven-plugin</artifactId> | |
| <version>${scalatest-maven-plugin}</version> | |
| <configuration> | |
| <reportsDirectory>${project.build.directory}/surefire-reports</reportsDirectory> | |
| <junitxml>.</junitxml> | |
| <argLine>-Duser.timezone=${project.timezone} -Dfile.encoding=${project.build.sourceEncoding} | |
| </argLine> | |
| <parallel>false</parallel> | |
| </configuration> | |
| <executions> | |
| <execution> | |
| <id>test</id> | |
| <goals> | |
| <goal>test</goal> | |
| </goals> | |
| </execution> | |
| </executions> | |
| </plugin> | |
| <plugin> | |
| <groupId>org.apache.maven.plugins</groupId> | |
| <artifactId>maven-deploy-plugin</artifactId> | |
| <version>${maven.deploy.plugin.version}</version> | |
| <configuration> | |
| <skip>true</skip> | |
| </configuration> | |
| </plugin> | |
| <plugin> | |
| <groupId>org.sonatype.plugins</groupId> | |
| <artifactId>nexus-staging-maven-plugin</artifactId> | |
| <version>${nexus.staging.maven.plugin.version}</version> | |
| <executions> | |
| <execution> | |
| <id>default-deploy</id> | |
| <phase>deploy</phase> | |
| <goals> | |
| <goal>deploy</goal> | |
| </goals> | |
| </execution> | |
| </executions> | |
| <configuration> | |
| <serverId>ossrh</serverId> | |
| <nexusUrl>https://oss.sonatype.org/</nexusUrl> | |
| <autoReleaseAfterClose>true</autoReleaseAfterClose> | |
| </configuration> | |
| </plugin> | |
| <plugin> | |
| <groupId>org.scoverage</groupId> | |
| <artifactId>scoverage-maven-plugin</artifactId> | |
| <version>${scoverage.plugin.version}</version> | |
| <configuration> | |
| <scalaVersion>${scala.version}</scalaVersion> | |
| <aggregateOnly>true</aggregateOnly> | |
| <!-- other parameters --> | |
| </configuration> | |
| </plugin> | |
| <plugin> | |
| <groupId>org.apache.maven.plugins</groupId> | |
| <artifactId>maven-site-plugin</artifactId> | |
| <version>${site.plugin.version}</version> | |
| <configuration> | |
| <skip>true</skip> | |
| </configuration> | |
| </plugin> | |
| <plugin> | |
| <groupId>org.apache.maven.plugins</groupId> | |
| <artifactId>maven-help-plugin</artifactId> | |
| <version>${maven.help.plugin.version}</version> | |
| <executions> | |
| <execution> | |
| <id>show-profiles</id> | |
| <phase>compile</phase> | |
| <goals> | |
| <goal>active-profiles</goal> | |
| </goals> | |
| </execution> | |
| </executions> | |
| </plugin> | |
| </plugins> | |
| <resources> | |
| <resource> | |
| <directory>src/main/resources</directory> | |
| <filtering>true</filtering> | |
| </resource> | |
| </resources> | |
| <testResources> | |
| <testResource> | |
| <directory>src/test/resources</directory> | |
| <filtering>true</filtering> | |
| </testResource> | |
| </testResources> | |
| </build> | |
| <profiles> | |
| <profile> | |
| <id>snapshot</id> | |
| <properties> | |
| <changelist>-SNAPSHOT</changelist> | |
| </properties> | |
| <distributionManagement> | |
| <snapshotRepository> | |
| <id>ossrh</id> | |
| <url>https://oss.sonatype.org/content/repositories/snapshots</url> | |
| </snapshotRepository> | |
| </distributionManagement> | |
| </profile> | |
| <profile> | |
| <id>release</id> | |
| <properties> | |
| <changelist></changelist> | |
| </properties> | |
| <build> | |
| <plugins> | |
| <plugin> | |
| <groupId>org.apache.maven.plugins</groupId> | |
| <artifactId>maven-gpg-plugin</artifactId> | |
| <version>${maven.gpg.plugin.version}</version> | |
| <executions> | |
| <execution> | |
| <id>sign-artifacts</id> | |
| <phase>verify</phase> | |
| <goals> | |
| <goal>sign</goal> | |
| </goals> | |
| </execution> | |
| </executions> | |
| </plugin> | |
| </plugins> | |
| </build> | |
| <distributionManagement> | |
| <repository> | |
| <id>ossrh</id> | |
| <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url> | |
| </repository> | |
| </distributionManagement> | |
| </profile> | |
| </profiles> | |
| </project> | |
| *************************************************************************************************************************** | |
| # mvn archetype # default # % cat sample/src/main/scala/com/commons/project/HelloWorld.scala | |
| *************************************************************************************************************************** | |
| package com.commons.project | |
| /** | |
| * @author ${user.name} | |
| */ | |
| object HelloWorld { | |
| def foo(x: Array[String]) = x.foldLeft("")((a, b) => a + b) | |
| def main(args: Array[String]) { | |
| println("Hello World!") | |
| println("concat arguments = " + foo(args)) | |
| } | |
| } | |
| *************************************************************************************************************************** | |
| # mvn archetype # default # % cat sample/src/test/scala/SimpleTestSuite.scala | |
| *************************************************************************************************************************** | |
| import org.scalatest.funsuite.AnyFunSuite | |
| class SimpleTestSuite extends AnyFunSuite { | |
| test("This should pass") { | |
| println("hello") | |
| assert(true) | |
| } | |
| } | |
| *************************************************************************************************************************** | |
| 2. Edit sample/pom.xml | |
| *************************************************************************************************************************** | |
| =========================================================================================================================== | |
| # Update # name | |
| =========================================================================================================================== | |
| <name>${project.artifactId}</name> | |
| <description>Scala App</description> | |
| <url>https://github.com/</url> | |
| =========================================================================================================================== | |
| # Update # properties | |
| =========================================================================================================================== | |
| <properties> | |
| <!-- <scala.version>2.12.10</scala.version> --> | |
| <!-- <scala.compat.version>2.12</scala.compat.version> --> | |
| <scala.version>3.5.1</scala.version> | |
| <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |
| <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | |
| <project.timezone>UTC</project.timezone> | |
| <!-- <java.version>1.8</java.version> --> | |
| <java.version>23</java.version> | |
| <scoverage.plugin.version>1.4.0</scoverage.plugin.version> | |
| <site.plugin.version>3.7.1</site.plugin.version> | |
| <!-- <scalatest.version>3.1.2</scalatest.version> --> | |
| <!-- <scalatest-maven-plugin>2.0.0</scalatest-maven-plugin> --> | |
| <!-- <scala.maven.plugin.version>4.4.0</scala.maven.plugin.version> --> | |
| <scalatest.version>3.2.19</scalatest.version> | |
| <scalatest-maven-plugin>2.2.0</scalatest-maven-plugin> | |
| <scala.maven.plugin.version>4.9.2</scala.maven.plugin.version> | |
| <maven-assembly-plugin.version>3.7.1</maven-assembly-plugin.version> | |
| <maven.compiler.plugin.version>3.8.1</maven.compiler.plugin.version> | |
| <maven.javadoc.plugin.version>3.2.0</maven.javadoc.plugin.version> | |
| <maven.source.plugin.version>3.2.1</maven.source.plugin.version> | |
| <maven.deploy.plugin.version>2.8.2</maven.deploy.plugin.version> | |
| <nexus.staging.maven.plugin.version>1.6.8</nexus.staging.maven.plugin.version> | |
| <maven.help.plugin.version>3.2.0</maven.help.plugin.version> | |
| <maven.gpg.plugin.version>1.6</maven.gpg.plugin.version> | |
| <maven.surefire.plugin.version>2.22.2</maven.surefire.plugin.version> | |
| </properties> | |
| =========================================================================================================================== | |
| # Update # scala3-library_3 | |
| =========================================================================================================================== | |
| <!--======SCALA======--> | |
| <!-- https://mvnrepository.com/artifact/org.scala-lang/scala3-library --> | |
| <dependency> | |
| <groupId>org.scala-lang</groupId> | |
| <artifactId>scala3-library_3</artifactId> | |
| <version>${scala.version}</version> | |
| </dependency> | |
| =========================================================================================================================== | |
| # Update # scalatest_3 | |
| =========================================================================================================================== | |
| <!--======Test======--> | |
| <!-- https://mvnrepository.com/artifact/org.scalatest/scalatest --> | |
| <dependency> | |
| <groupId>org.scalatest</groupId> | |
| <artifactId>scalatest_3</artifactId> | |
| <version>${scalatest.version}</version> | |
| <scope>test</scope> | |
| </dependency> | |
| =========================================================================================================================== | |
| # Update # maven-compiler-plugin # maven-assembly-plugin | |
| =========================================================================================================================== | |
| <plugin> | |
| <groupId>org.apache.maven.plugins</groupId> | |
| <artifactId>maven-compiler-plugin</artifactId> | |
| <version>${maven.compiler.plugin.version}</version> | |
| <configuration> | |
| <source>${java.version}</source> | |
| <target>${java.version}</target> | |
| </configuration> | |
| <executions> | |
| <execution> | |
| <id>default-compile</id> | |
| <phase>none</phase> | |
| </execution> | |
| </executions> | |
| </plugin> | |
| <plugin> | |
| <groupId>org.apache.maven.plugins</groupId> | |
| <artifactId>maven-assembly-plugin</artifactId> | |
| <version>${maven-assembly-plugin.version}</version> | |
| <configuration> | |
| <descriptorRefs> | |
| <descriptorRef>jar-with-dependencies</descriptorRef> | |
| </descriptorRefs> | |
| <archive> | |
| <manifest> | |
| <mainClass>com.commons.project.MainClass</mainClass> | |
| </manifest> | |
| </archive> | |
| </configuration> | |
| <executions> | |
| <execution> | |
| <phase>package</phase> | |
| <goals> | |
| <goal>single</goal> | |
| </goals> | |
| </execution> | |
| </executions> | |
| </plugin> | |
| =========================================================================================================================== | |
| # Update # scala-maven-plugin | |
| =========================================================================================================================== | |
| <plugin> | |
| <groupId>net.alchim31.maven</groupId> | |
| <artifactId>scala-maven-plugin</artifactId> | |
| <version>${scala.maven.plugin.version}</version> | |
| <configuration> | |
| <jvmArgs> | |
| <jvmArg>-Xms64m</jvmArg> | |
| <jvmArg>-Xmx1024m</jvmArg> | |
| </jvmArgs> | |
| </configuration> | |
| <executions> | |
| <execution> | |
| <id>compile</id> | |
| <goals> | |
| <goal>compile</goal> | |
| </goals> | |
| </execution> | |
| <execution> | |
| <id>test-compile</id> | |
| <goals> | |
| <goal>testCompile</goal> | |
| </goals> | |
| </execution> | |
| <execution> | |
| <id>add-source</id> | |
| <goals> | |
| <goal>add-source</goal> | |
| </goals> | |
| </execution> | |
| </executions> | |
| </plugin> | |
| =========================================================================================================================== | |
| # Add # maven-jxr-plugin | |
| =========================================================================================================================== | |
| <reporting> | |
| <plugins> | |
| <plugin> | |
| <groupId>org.apache.maven.plugins</groupId> | |
| <artifactId>maven-jxr-plugin</artifactId> | |
| <version>3.6.0</version> | |
| <reportSets> | |
| <reportSet> | |
| <reports> | |
| <report>jxr-no-fork</report> | |
| <report>test-jxr-no-fork</report> | |
| </reports> | |
| </reportSet> | |
| </reportSets> | |
| </plugin> | |
| </plugins> | |
| </reporting> | |
| =========================================================================================================================== | |
| *************************************************************************************************************************** | |
| # Edited pom.xml # % cat sample/pom.xml | |
| *************************************************************************************************************************** | |
| <?xml version="1.0" encoding="UTF-8"?> | |
| <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" | |
| 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> | |
| <groupId>com.commons.project</groupId> | |
| <artifactId>sample</artifactId> | |
| <version>1.0-SNAPSHOT</version> | |
| <packaging>jar</packaging> | |
| <name>${project.artifactId}</name> | |
| <description>Scala App</description> | |
| <url>https://github.com/</url> | |
| <!--======Uncomment if you need to deploy the project======--> | |
| <!--<scm>--> | |
| <!-- <connection></connection>--> | |
| <!-- <developerConnection></developerConnection>--> | |
| <!-- <url></url>--> | |
| <!--</scm>--> | |
| <!--<licenses>--> | |
| <!-- <license>--> | |
| <!-- <name>The Apache License, Version 2.0</name>--> | |
| <!-- <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>--> | |
| <!-- </license>--> | |
| <!--</licenses>--> | |
| <!--<developers>--> | |
| <!-- <developer>--> | |
| <!-- <id>id</id>--> | |
| <!-- <name>YOUR NAME</name>--> | |
| <!-- <email>EMAIL</email>--> | |
| <!-- </developer>--> | |
| <!--</developers>--> | |
| <repositories> | |
| <repository> | |
| <id>maven.apache.org</id> | |
| <url>https://repo.maven.apache.org/maven2</url> | |
| </repository> | |
| <repository> | |
| <id>ossrh-snapshots</id> | |
| <url>https://oss.sonatype.org/content/repositories/snapshots/</url> | |
| </repository> | |
| </repositories> | |
| <properties> | |
| <!-- <scala.version>2.12.10</scala.version> --> | |
| <!-- <scala.compat.version>2.12</scala.compat.version> --> | |
| <scala.version>3.5.1</scala.version> | |
| <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |
| <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | |
| <project.timezone>UTC</project.timezone> | |
| <!-- <java.version>1.8</java.version> --> | |
| <java.version>23</java.version> | |
| <scoverage.plugin.version>1.4.0</scoverage.plugin.version> | |
| <site.plugin.version>3.7.1</site.plugin.version> | |
| <!-- <scalatest.version>3.1.2</scalatest.version> --> | |
| <!-- <scalatest-maven-plugin>2.0.0</scalatest-maven-plugin> --> | |
| <!-- <scala.maven.plugin.version>4.4.0</scala.maven.plugin.version> --> | |
| <scalatest.version>3.2.19</scalatest.version> | |
| <scalatest-maven-plugin>2.2.0</scalatest-maven-plugin> | |
| <scala.maven.plugin.version>4.9.2</scala.maven.plugin.version> | |
| <maven-assembly-plugin.version>3.7.1</maven-assembly-plugin.version> | |
| <maven.compiler.plugin.version>3.8.1</maven.compiler.plugin.version> | |
| <maven.javadoc.plugin.version>3.2.0</maven.javadoc.plugin.version> | |
| <maven.source.plugin.version>3.2.1</maven.source.plugin.version> | |
| <maven.deploy.plugin.version>2.8.2</maven.deploy.plugin.version> | |
| <nexus.staging.maven.plugin.version>1.6.8</nexus.staging.maven.plugin.version> | |
| <maven.help.plugin.version>3.2.0</maven.help.plugin.version> | |
| <maven.gpg.plugin.version>1.6</maven.gpg.plugin.version> | |
| <maven.surefire.plugin.version>2.22.2</maven.surefire.plugin.version> | |
| </properties> | |
| <dependencies> | |
| <!--======SCALA======--> | |
| <!-- https://mvnrepository.com/artifact/org.scala-lang/scala3-library --> | |
| <dependency> | |
| <groupId>org.scala-lang</groupId> | |
| <artifactId>scala3-library_3</artifactId> | |
| <version>${scala.version}</version> | |
| </dependency> | |
| <!--======SPARK PROJECT======--> | |
| <!--<dependency>--> | |
| <!-- <groupId>org.apache.spark</groupId>--> | |
| <!-- <artifactId>spark-core_${scala.compat.version}</artifactId>--> | |
| <!-- <version>${spark.version}</version>--> | |
| <!-- <scope>provided</scope>--> | |
| <!--</dependency>--> | |
| <!--<dependency>--> | |
| <!-- <groupId>org.apache.spark</groupId>--> | |
| <!-- <artifactId>spark-sql_${scala.compat.version}</artifactId>--> | |
| <!-- <version>${spark.version}</version>--> | |
| <!-- <scope>provided</scope>--> | |
| <!--</dependency>--> | |
| <!--<dependency>--> | |
| <!-- <groupId>org.apache.spark</groupId>--> | |
| <!-- <artifactId>spark-mllib_${scala.compat.version}</artifactId>--> | |
| <!-- <version>${spark.version}</version>--> | |
| <!-- <scope>provided</scope>--> | |
| <!--</dependency>--> | |
| <!--<dependency>--> | |
| <!-- <groupId>org.apache.spark</groupId>--> | |
| <!-- <artifactId>spark-hive_${scala.compat.version}</artifactId>--> | |
| <!-- <version>${spark.version}</version>--> | |
| <!-- <scope>provided</scope>--> | |
| <!--</dependency>--> | |
| <!--======TYPESAFE CONFIG======--> | |
| <!--<dependency>--> | |
| <!-- <groupId>com.typesafe</groupId>--> | |
| <!-- <artifactId>config</artifactId>--> | |
| <!-- <version>1.4.0</version>--> | |
| <!--</dependency>--> | |
| <!--======Test======--> | |
| <!-- https://mvnrepository.com/artifact/org.scalatest/scalatest --> | |
| <dependency> | |
| <groupId>org.scalatest</groupId> | |
| <artifactId>scalatest_3</artifactId> | |
| <version>${scalatest.version}</version> | |
| <scope>test</scope> | |
| </dependency> | |
| </dependencies> | |
| <build> | |
| <plugins> | |
| <plugin> | |
| <groupId>org.apache.maven.plugins</groupId> | |
| <artifactId>maven-compiler-plugin</artifactId> | |
| <version>${maven.compiler.plugin.version}</version> | |
| <configuration> | |
| <source>${java.version}</source> | |
| <target>${java.version}</target> | |
| </configuration> | |
| <executions> | |
| <execution> | |
| <id>default-compile</id> | |
| <phase>none</phase> | |
| </execution> | |
| </executions> | |
| </plugin> | |
| <plugin> | |
| <groupId>org.apache.maven.plugins</groupId> | |
| <artifactId>maven-assembly-plugin</artifactId> | |
| <version>${maven-assembly-plugin.version}</version> | |
| <configuration> | |
| <descriptorRefs> | |
| <descriptorRef>jar-with-dependencies</descriptorRef> | |
| </descriptorRefs> | |
| <archive> | |
| <manifest> | |
| <mainClass>com.commons.project.MainClass</mainClass> | |
| </manifest> | |
| </archive> | |
| </configuration> | |
| <executions> | |
| <execution> | |
| <phase>package</phase> | |
| <goals> | |
| <goal>single</goal> | |
| </goals> | |
| </execution> | |
| </executions> | |
| </plugin> | |
| <plugin> | |
| <groupId>net.alchim31.maven</groupId> | |
| <artifactId>scala-maven-plugin</artifactId> | |
| <version>${scala.maven.plugin.version}</version> | |
| <configuration> | |
| <jvmArgs> | |
| <jvmArg>-Xms64m</jvmArg> | |
| <jvmArg>-Xmx1024m</jvmArg> | |
| </jvmArgs> | |
| </configuration> | |
| <executions> | |
| <execution> | |
| <id>compile</id> | |
| <goals> | |
| <goal>compile</goal> | |
| </goals> | |
| </execution> | |
| <execution> | |
| <id>test-compile</id> | |
| <goals> | |
| <goal>testCompile</goal> | |
| </goals> | |
| </execution> | |
| <execution> | |
| <id>add-source</id> | |
| <goals> | |
| <goal>add-source</goal> | |
| </goals> | |
| </execution> | |
| </executions> | |
| </plugin> | |
| <plugin> | |
| <groupId>org.apache.maven.plugins</groupId> | |
| <artifactId>maven-javadoc-plugin</artifactId> | |
| <version>${maven.javadoc.plugin.version}</version> | |
| </plugin> | |
| <plugin> | |
| <groupId>org.apache.maven.plugins</groupId> | |
| <artifactId>maven-source-plugin</artifactId> | |
| <version>${maven.source.plugin.version}</version> | |
| <configuration> | |
| <outputDirectory>target</outputDirectory> | |
| <attach>true</attach> | |
| </configuration> | |
| <executions> | |
| <execution> | |
| <id>attach-sources</id> | |
| <goals> | |
| <goal>jar</goal> | |
| </goals> | |
| </execution> | |
| </executions> | |
| </plugin> | |
| <plugin> | |
| <groupId>org.apache.maven.plugins</groupId> | |
| <artifactId>maven-surefire-plugin</artifactId> | |
| <version>${maven.surefire.plugin.version}</version> | |
| <configuration> | |
| <skipTests>true</skipTests> | |
| </configuration> | |
| </plugin> | |
| <plugin> | |
| <groupId>org.scalatest</groupId> | |
| <artifactId>scalatest-maven-plugin</artifactId> | |
| <version>${scalatest-maven-plugin}</version> | |
| <configuration> | |
| <reportsDirectory>${project.build.directory}/surefire-reports</reportsDirectory> | |
| <junitxml>.</junitxml> | |
| <argLine>-Duser.timezone=${project.timezone} -Dfile.encoding=${project.build.sourceEncoding} | |
| </argLine> | |
| <parallel>false</parallel> | |
| </configuration> | |
| <executions> | |
| <execution> | |
| <id>test</id> | |
| <goals> | |
| <goal>test</goal> | |
| </goals> | |
| </execution> | |
| </executions> | |
| </plugin> | |
| <plugin> | |
| <groupId>org.apache.maven.plugins</groupId> | |
| <artifactId>maven-deploy-plugin</artifactId> | |
| <version>${maven.deploy.plugin.version}</version> | |
| <configuration> | |
| <skip>true</skip> | |
| </configuration> | |
| </plugin> | |
| <plugin> | |
| <groupId>org.sonatype.plugins</groupId> | |
| <artifactId>nexus-staging-maven-plugin</artifactId> | |
| <version>${nexus.staging.maven.plugin.version}</version> | |
| <executions> | |
| <execution> | |
| <id>default-deploy</id> | |
| <phase>deploy</phase> | |
| <goals> | |
| <goal>deploy</goal> | |
| </goals> | |
| </execution> | |
| </executions> | |
| <configuration> | |
| <serverId>ossrh</serverId> | |
| <nexusUrl>https://oss.sonatype.org/</nexusUrl> | |
| <autoReleaseAfterClose>true</autoReleaseAfterClose> | |
| </configuration> | |
| </plugin> | |
| <plugin> | |
| <groupId>org.scoverage</groupId> | |
| <artifactId>scoverage-maven-plugin</artifactId> | |
| <version>${scoverage.plugin.version}</version> | |
| <configuration> | |
| <scalaVersion>${scala.version}</scalaVersion> | |
| <aggregateOnly>true</aggregateOnly> | |
| <!-- other parameters --> | |
| </configuration> | |
| </plugin> | |
| <plugin> | |
| <groupId>org.apache.maven.plugins</groupId> | |
| <artifactId>maven-site-plugin</artifactId> | |
| <version>${site.plugin.version}</version> | |
| <configuration> | |
| <skip>true</skip> | |
| </configuration> | |
| </plugin> | |
| <plugin> | |
| <groupId>org.apache.maven.plugins</groupId> | |
| <artifactId>maven-help-plugin</artifactId> | |
| <version>${maven.help.plugin.version}</version> | |
| <executions> | |
| <execution> | |
| <id>show-profiles</id> | |
| <phase>compile</phase> | |
| <goals> | |
| <goal>active-profiles</goal> | |
| </goals> | |
| </execution> | |
| </executions> | |
| </plugin> | |
| </plugins> | |
| <resources> | |
| <resource> | |
| <directory>src/main/resources</directory> | |
| <filtering>true</filtering> | |
| </resource> | |
| </resources> | |
| <testResources> | |
| <testResource> | |
| <directory>src/test/resources</directory> | |
| <filtering>true</filtering> | |
| </testResource> | |
| </testResources> | |
| </build> | |
| <profiles> | |
| <profile> | |
| <id>snapshot</id> | |
| <properties> | |
| <changelist>-SNAPSHOT</changelist> | |
| </properties> | |
| <distributionManagement> | |
| <snapshotRepository> | |
| <id>ossrh</id> | |
| <url>https://oss.sonatype.org/content/repositories/snapshots</url> | |
| </snapshotRepository> | |
| </distributionManagement> | |
| </profile> | |
| <profile> | |
| <id>release</id> | |
| <properties> | |
| <changelist></changelist> | |
| </properties> | |
| <build> | |
| <plugins> | |
| <plugin> | |
| <groupId>org.apache.maven.plugins</groupId> | |
| <artifactId>maven-gpg-plugin</artifactId> | |
| <version>${maven.gpg.plugin.version}</version> | |
| <executions> | |
| <execution> | |
| <id>sign-artifacts</id> | |
| <phase>verify</phase> | |
| <goals> | |
| <goal>sign</goal> | |
| </goals> | |
| </execution> | |
| </executions> | |
| </plugin> | |
| </plugins> | |
| </build> | |
| <distributionManagement> | |
| <repository> | |
| <id>ossrh</id> | |
| <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url> | |
| </repository> | |
| </distributionManagement> | |
| </profile> | |
| </profiles> | |
| <reporting> | |
| <plugins> | |
| <plugin> | |
| <groupId>org.apache.maven.plugins</groupId> | |
| <artifactId>maven-jxr-plugin</artifactId> | |
| <version>3.6.0</version> | |
| <reportSets> | |
| <reportSet> | |
| <reports> | |
| <report>jxr-no-fork</report> | |
| <report>test-jxr-no-fork</report> | |
| </reports> | |
| </reportSet> | |
| </reportSets> | |
| </plugin> | |
| </plugins> | |
| </reporting> | |
| </project> | |
| *************************************************************************************************************************** | |
| 3. Add App.scala | |
| % ls sample/src/main/scala/com/commons/project | |
| % rm -rf sample/src/main/scala/com/commons/project/HelloWorld.scala | |
| % nano sample/src/main/scala/com/commons/project/App.scala | |
| % cat sample/src/main/scala/com/commons/project/App.scala | |
| *************************************************************************************************************************** | |
| package com.commons.project | |
| /** | |
| * @author ${user.name} | |
| */ | |
| object App { | |
| def printSystemProperties() = { | |
| println(String.format("OS Name: %s", System.getProperty("os.name"))) | |
| println(String.format("OS Version: %s", System.getProperty("os.version"))) | |
| println(String.format("OS Architecture: %s", System.getProperty("os.arch"))) | |
| println(String.format("Java Version: %s", System.getProperty("java.version"))) | |
| println(String.format("Java Vendor Version: %s", System.getProperty("java.vendor.version"))) | |
| println(String.format("Java VM Name: %s", System.getProperty("java.vm.name"))) | |
| println(String.format("Scala Version Number String: %s", util.Properties.versionNumberString)) | |
| println(String.format("Scala Version String: %s", util.Properties.versionString)) | |
| println(String.format("Scala Version Msg: %s", util.Properties.versionMsg)) | |
| // println(System.getProperties().list(System.out)); | |
| } | |
| def concat(x: Array[String]) = x.foldLeft("")((a, b) => a + b) | |
| def main(args: Array[String]) = { | |
| printSystemProperties() | |
| println("Concat Array[String]: " + concat(args)) | |
| } | |
| } | |
| *************************************************************************************************************************** | |
| 4. Add AppTestSuite.scala | |
| % ls sample/src/test/scala | |
| % rm -rf sample/src/test/scala/SimpleTestSuite.scala | |
| % mkdir -p sample/src/test/scala/com/commons/project | |
| % nano sample/src/test/scala/com/commons/project/AppTestSuite.scala | |
| % cat sample/src/test/scala/com/commons/project/AppTestSuite.scala | |
| *************************************************************************************************************************** | |
| package com.commons.project; | |
| import org.scalatest.funsuite.AnyFunSuite | |
| /** | |
| * Unit test for simple App. | |
| */ | |
| class AppTestSuite extends AnyFunSuite { | |
| test("This should pass") { | |
| App.printSystemProperties() | |
| assert(true) | |
| } | |
| test("Invoking App concat should concat array elements") { | |
| val array = Array(util.Properties.versionNumberString, util.Properties.versionString, util.Properties.versionMsg) | |
| val x = array.foldLeft("")((a, b) => a + b) | |
| val y = App.concat(array) | |
| assert(x == y) | |
| } | |
| } | |
| *************************************************************************************************************************** | |
| # Tree recursive directory listing # % tree | |
| *************************************************************************************************************************** | |
| . | |
| └── sample | |
| ├── pom.xml | |
| └── src | |
| ├── main | |
| │ └── scala | |
| │ └── com | |
| │ └── commons | |
| │ └── project | |
| │ └── App.scala | |
| └── test | |
| └── scala | |
| └── com | |
| └── commons | |
| └── project | |
| └── AppTestSuite.scala | |
| 13 directories, 3 files | |
| *************************************************************************************************************************** | |
| 5. mvn package | |
| *************************************************************************************************************************** | |
| % cd sample | |
| [ | |
| # mvn validate - validate the project is correct and all necessary information is available | |
| # mvn compile - compile the source code of the project | |
| # mvn test - test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed | |
| # mvn package - take the compiled code and package it in its distributable format, such as a JAR. | |
| # mvn verify - run any checks on results of integration tests to ensure quality criteria are met | |
| # mvn install - install the package into the local repository, for use as a dependency in other projects locally | |
| # mvn deploy - done in the build environment, copies the final package to the remote repository for sharing with other developers and projects. | |
| ] | |
| % mvn dependency:tree | |
| % mvn package | |
| *************************************************************************************************************************** | |
| 6. mvn test | |
| *************************************************************************************************************************** | |
| % mvn test | |
| % mvn -Dtest=AppTestSuite test | |
| % mvn -Dtest=org.scalatest.funsuite.AnyFunSuite.AppTestSuite test | |
| *************************************************************************************************************************** | |
| 7. mvn # Surefire Report | |
| *************************************************************************************************************************** | |
| % mvn surefire-report:report | |
| % jwebserver --version | |
| % jwebserver --directory $(pwd)/target/reports --port 8000 | |
| # Terminal Window # curl # open | |
| % curl http://127.0.0.1:8000/surefire.html | |
| % open http://127.0.0.1:8000/surefire.html | |
| *************************************************************************************************************************** | |
| 8. mvn scala | |
| *************************************************************************************************************************** | |
| # Original Terminal Window | |
| <control + c> | |
| % mvn scala:compile | |
| % mvn scala:testCompile | |
| % mvn scala:run -DmainClass=com.commons.project.App | |
| *************************************************************************************************************************** | |
| ########################################################################################################################### | |
| ########################################################################################################################### | |
| # Maven Wrapper # Scala | |
| ########################################################################################################################### | |
| *************************************************************************************************************************** | |
| 1. mvn wrapper | |
| *************************************************************************************************************************** | |
| [ | |
| % mvn clean | |
| ] | |
| # Setup the Maven Wrapper using the Maven Wrapper Plugin with its provided wrapper goal | |
| % mvn wrapper:wrapper | |
| # For Maven, install a specific version of Apache Maven, put it on the PATH and then run the mvn command | |
| [ | |
| % mvn clean install | |
| ] | |
| % For Maven Wrapper, run wrapper scripts | |
| % ./mvnw clean install | |
| # Windows | |
| [ | |
| > mvnw.cmd clean install | |
| ] | |
| *************************************************************************************************************************** | |
| 2. mvnw test | |
| *************************************************************************************************************************** | |
| % ./mvnw test | |
| % ./mvnw -Dtest=AppTestSuite test | |
| % ./mvnw -Dtest=org.scalatest.funsuite.AnyFunSuite.AppTestSuite test | |
| *************************************************************************************************************************** | |
| 3. mvnw # Surefire Report | |
| *************************************************************************************************************************** | |
| % ./mvnw surefire-report:report | |
| % jwebserver --version | |
| % jwebserver --directory $(pwd)/target/reports --port 8000 | |
| # Terminal Window # curl # open | |
| % curl http://127.0.0.1:8000/surefire.html | |
| % open http://127.0.0.1:8000/surefire.html | |
| *************************************************************************************************************************** | |
| 4. mvnw scala | |
| *************************************************************************************************************************** | |
| # Original Terminal Window | |
| <control + c> | |
| % ./mvnw scala:compile | |
| % ./mvnw scala:testCompile | |
| % ./mvnw scala:run -DmainClass=com.commons.project.App | |
| *************************************************************************************************************************** | |
| ########################################################################################################################### | |
| ########################################################################################################################### | |
| *************************************************************************************************************************** | |
| # jar | |
| *************************************************************************************************************************** | |
| % jar tvf target/sample-1.0-SNAPSHOT.jar | |
| % jar tvf target/sample-1.0-SNAPSHOT-sources.jar | |
| % jar tvf target/sample-1.0-SNAPSHOT-jar-with-dependencies.jar | |
| *************************************************************************************************************************** | |
| # javap | |
| *************************************************************************************************************************** | |
| % javap target/classes/com/commons/project/App.class | |
| *************************************************************************************************************************** | |
| # java | |
| *************************************************************************************************************************** | |
| % java -classpath target/sample-1.0-SNAPSHOT-jar-with-dependencies.jar com.commons.project.App Maven, Scala, Java | |
| % java -classpath target/sample-1.0-SNAPSHOT-jar-with-dependencies.jar com.commons.project.App "Maven", " Scala", " Java" | |
| *************************************************************************************************************************** | |
| ########################################################################################################################### | |
| ########################################################################################################################### | |
| # Scala | |
| ########################################################################################################################### | |
| *************************************************************************************************************************** | |
| # Linux | |
| [ | |
| % curl -L https://github.com/coursier/coursier/releases/latest/download/cs-x86_64-pc-linux.gz | gzip -d > cs && chmod +x cs && ./cs setup | |
| # Or | |
| % curl -L https://github.com/VirtusLab/coursier-m1/releases/latest/download/cs-aarch64-pc-linux.gz | gzip -d > cs && chmod +x cs && ./cs setup | |
| ] | |
| # macOS | |
| [ | |
| % brew install coursier/formulas/coursier && cs setup | |
| ] | |
| *************************************************************************************************************************** | |
| % scala version | |
| % cs version | |
| % scala run --classpath target/sample-1.0-SNAPSHOT.jar --main-class com.commons.project.App -- Coursier, Scala, Center | |
| % scala run --classpath target/sample-1.0-SNAPSHOT.jar --main-class com.commons.project.App -- "Coursier", " Scala", " Center" | |
| % scala run --classpath target/sample-1.0-SNAPSHOT-jar-with-dependencies.jar --main-class com.commons.project.App -- Coursier, Scala, Center | |
| % scala run --classpath target/sample-1.0-SNAPSHOT-jar-with-dependencies.jar --main-class com.commons.project.App -- "Coursier", " Scala", " Center" | |
| *************************************************************************************************************************** | |
| ########################################################################################################################### | |
| ########################################################################################################################### | |
| # Scala # scala repl # scalac # scala run | |
| ########################################################################################################################### | |
| *************************************************************************************************************************** | |
| % scala | |
| # Or | |
| % scala repl | |
| # Or | |
| % scala-cli | |
| > util.Properties.versionNumberString | |
| > util.Properties.versionString | |
| > util.Properties.versionMsg | |
| > :exit | |
| % mkdir -p "macOSAArch64/Scala" && cat > macOSAArch64/Scala/program.scala << EOF | |
| object method { def main(args: Array[String]) = { println("Main Method Scala Version Number String: " + util.Properties.versionNumberString) } } | |
| EOF | |
| % cd macOSAArch64/Scala | |
| % scalac program.scala | |
| % scala run program.scala | |
| [ | |
| Compiling project (Scala 3.6.2, JVM (8)) | |
| Compiled project (Scala 3.6.2, JVM (8)) | |
| Main Method Scala Version Number String: 2.13.15 | |
| ] | |
| % mkdir -p "macOSAArch64/Scala3" && cat > macOSAArch64/Scala3/program.scala << EOF | |
| @main def method() = println("Main Method Scala Version Number String: " + util.Properties.versionNumberString) | |
| EOF | |
| % cd macOSAArch64/Scala3 | |
| % scalac program.scala | |
| % scala run program.scala | |
| [ | |
| Compiling project (Scala 3.6.2, JVM (8)) | |
| Compiled project (Scala 3.6.2, JVM (8)) | |
| Main Method Scala Version Number String: 2.13.15 | |
| ] | |
| *************************************************************************************************************************** | |
| ########################################################################################################################### | |
| // Credits | |
| /* | |
| https://scala-lang.org/ | |
| https://openjdk.org/ | |
| https://maven.apache.org/ | |
| https://scala-sbt.org/ | |
| https://scala.epfl.ch/ | |
| https://get-coursier.io/ | |
| https://scalatest.org/ | |
| */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment