How to embed pom descriptors in a jar - sbt

When a jar is created using Maven. The META-INF directory in the jar contains sub-directory maven/group-id/artifact-id with pom.xml and pom.properties. How to do it with SBT?
Is there an option of a plugin that does that?

You can always publish 'maven style' with sbt - This will create the pom and pom.properties correctly.
To do this, you can use:
publishMavenStyle := true
And you will probably need to add the extra information required by the pom. To do this, set pomExtra:
pomExtra :=
<licenses>
<license>
<name>Apache 2</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
For more information, see the docs: Publishing and the following describes in detail how to publish to a maven repo: Deploying to Sonatype.

Related

Katalon with external jar as dependency and not as a project resource?

When using our Git based Katalon Studio project, we need to use an external jar.
According to the Katalon docs, as can be seen here, we need to paste the jar in our Drivers folder.
But the meaning of that is that we are pushing the jar into git, a pattern we don't really like (e.g. when new versions of the jar will be available, we can't simply use "latest")
From our Java projects we are customs to use dependencies in our projects/POM file, so the project's Git is not holding the dependencies jars.
Is there something similar in Katalon?
Imagination is key here. I simply used ant because why not . . .
Here is a dead simple build.xml, simply put at it at top level of your project.
<project name=app-tests" default="dist" basedir=".">
<description>
gets the dependencies
</description>
<!-- set global properties for this build -->
<property name="dist" location="Drivers"/>
<target name="install">
<mkdir dir="${dist}"/>
<!-- Joda Time -->
<get src="http://central.maven.org/maven2/joda-time/joda-time/2.10.1/joda-time-2.10.1.jar"
dest="${dist}"
verbose="true"
usetimestamp="true"/>
<!-- ibatis common -->
<get src="https://repository.liferay.com/nexus/content/repositories/public/org/apache/ibatis-
common/2.2.0/ibatis-common-2.2.0.jar"
dest="${dist}"
verbose="true"
usetimestamp="true"/>
<!-- json simple -->
<get src="https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/json-simple/json-simple-1.1.1.jar"
dest="${dist}"
verbose="true"
usetimestamp="true"/>
</target>
</project>
Then run:
ant install
One could also do this with some bash action with curl or wget get kinda like so:
wget -P ./Drivers/ http://central.maven.org/maven2/joda-time/joda-time/2.10.1/joda-time-2.10.1.jar
Then pop a few of those into a build.sh and you're good to go.
Remember to restart Katalon for the the new items in the Drivers folder to take effect.
Enjoy!
My solution is: create a maven project under the same root-directory with katalon project, and add 'maven-dependency-plugin' plugin in the POM file,when run 'mvn clean packge', copy the target jar to the Drivers directory, and keep the jar in Drivers dir do not commit to git server.

Specify jar structure in sbt assembly

When sbt-assembly builds a fat jar, it places all the dependencies in the main folder. I need to construct a jar that looks like this
--domain
domain classes
-- lib
dependency classes
is it possible to do this with sbt assembly, or any other plugin?
If you want to seperate your app jar file and your dependecy jar files, here is the most practical method i found with sbt;
Create project/plugins.sbt file if not exists and add following line:
addSbtPlugin("org.xerial.sbt" % "sbt-pack" % "0.8.0")
After adding this line refresh your project.
Note: Plugin version might change in time.
When sbt refresh finishes update your build.sbt file like this:
lazy val MyApp = project.in(file("."))
.settings(artifactName := {(
sv: ScalaVersion,
module: ModuleID,
artifact: Artifact) => "MyApp.jar"
})
.settings(packSettings)
Then run:
sbt pack
Or if you're doing this for child project, run this:
sbt "project childproject" clean pack
This will nicely seperate your main jar file and your dependency jars.
Your app jar will be in target scala folder.
Your dependencies will be in target/pack/lib.
In this way you can deploy your dependencies once.
And whenever you change your app, you can just deploy your app jar file.
So in every change you don't have to deploy an uber jar file.
Also in production, you can run your app like:
java -cp "MyApp.jar:dependency_jars_folder/*" com.myapp.App

xsbt-web multi-module project: package some modules to jars, others to wars

I'm using sbt 0.13.8 and xsbt-web-plugin 2.0.3
I have a multi-module sbt project. When packaged, one of the modules should be in the form of a war file. All of the others in jar files.
When I add the xsbt-web plugin, packaging generates jars and wars for all modules. How can I tell the xsbt-web plugin to apply itself only to the module that should be packaged as a war?
I've already found one solution, which is to mutate the packagedArtifacts list for each non-war module:
packagedArtifacts <<= packagedArtifacts map { as => as.filter(_._1.`type` != "war") }
However, this is a non-local change which I would have to apply to each new non-war module that I (or a team member) might create.
I do not consider this a duplicate of the StackOverflow issue How to “package” some modules to jars and others to wars in multi-module build with single task? since I am not using assembly.
Note that the jars for the jar modules and the wars for the war modules, which are currently being generated, work splendidly. I'm only trying to avoid the situation where somebody tries to deploy a war that was meant to be a jar.
This was a bug in version 2.0.3 -- thanks for discovering it! I've fixed it in 2.0.4.
To enable .war file publishing for a single module in a multi-module project:
Add xsbt-web-plugin in project/plugins.sbt
Enable the WarPlugin plugin in [webproject]/build.sbt
project/plugins.sbt:
addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "2.0.4")
[webproject]/build.sbt:
enablePlugins(WarPlugin)
You can find a full example of this at https://earldouglas.com/ext/stackoverflow.com/questions/31683637/

sbt publish assembly jar with a pom

I am able to build one of my multi-project's jars as a single jar and then publish it How do I publish a fat JAR (JAR with dependencies) using sbt and sbt-release?
However, the associated pom.xml is not published with it.
How can I create and publish the pom.xml (and ivy file) descriptors for an sbt-assembly jar?
My project is lions-share.
Do you need to publish the contents of an existing pom.xml file, or can you let sbt generate the pom's contents for you? If the latter, consider using pomExtra:
pomExtra := (
<url>http://jsuereth.com/scala-arm</url>
<licenses>
<license>
<name>BSD-style</name>
<url>http://www.opensource.org/licenses/bsd-license.php</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<url>git#github.com:jsuereth/scala-arm.git</url>
<connection>scm:git:git#github.com:jsuereth/scala-arm.git</connection>
</scm>
<developers>
<developer>
<id>jsuereth</id>
<name>Josh Suereth</name>
<url>http://jsuereth.com</url>
</developer>
</developers>)
If you are making your fat jar via sbt clean assembly and want to include .pom with the jar, use sbt clean makePom assembly. This will automatically create the .pom file with the .jar file

Create standalone jar using SBT

I was a heavy Maven user and now I'm gradually using SBT for some of my projects.
I'd like to know how could I use SBT to create a standalone Java project? This project should be packaged as a JAR file and this JAR file would be used as a dependency in another SBT project.
In Maven, I could tell in my pom.xml what type of artifact it should produce when I build it. Is there something similar that I can do in SBT?
There is a difference between standalone and making a project useable as a dependency or another project. In the first case, you would use a plugin such as sbt-assembly. What it will do is create one jar file containing the project class files along with all of its dependencies. If you write an application, what you get is a double-clickable jar that you can execute from anywhere.
If you want to use your project A as a dependency for another project B, you have different options. You could just package the class files of A, using sbt package (answer of #Channing Walton). Then you could drop the resulting .jar file in the lib directory of project B. However, if A also requires libraries, you must make sure that they also end up in project B's libraries.
A better approach is to publish your project. You can do that purely on your local machine, using sbt publish-local. That will store the jar as produced by package in a special local directory which can be accessed from sbt in another project, along with a POM file that contains the dependencies of A. It will use a group-ID (organization) and artifact-ID (name) and a version of your project A. For example, in build.sbt:
name := "projecta"
version := "0.1.0-SNAPSHOT"
organization := "com.github.myname"
scalaVersion := "2.10.3"
publishMavenStyle := true
After publishing with sbt publish-local, you can add the following dependency to your project B:
libraryDependencies += "com.github.myname" %% "projecta" % "0.1.0-SNAPSHOT"
If you have a pure Java project, you can omit the Scala version suffix, i.e. in Project A:
crossPaths := false
autoScalaLibrary := false
And then in Project B:
libraryDependencies += "com.github.myname" % "projecta" % "0.1.0-SNAPSHOT"
(using only one % character between group and artifact ID).
More on publishing in the sbt documentation.
'sbt package' will produce a jar file.
If you want it to be executable you need to add the following to your .sbt config:
mainClass in Compile := Some("your.main.Class")
Sure, you can use 'sbt package' command, it creates a jar file but this jar will be without any dependencies. To run it necessary to specify 'classpath' arg to the libraries.
In your case you wish a standalone runnable file. And you need to add the dependencies.
To do this you can use 'assembly' plugin for SBT, see https://github.com/sbt/sbt-assembly/
Afterward you can just run 'sbt assembly' command, it provides a fat jar file with all dependencies that you can deploy and run anywhere and at any time.
For details see this article
publishLocal
builds the artifact and publish in the local Ivy repository making it available for your local project dependencies.
publishM2
same as above, but the artifact is published in local Maven repo instead of Ivy repo.
I think the easiest way to produce a stand-alone jar with your project in it,
is sadly not lying inside sbt.
I personally use my IDE: Intellij to make the jar (through the 'build artifact' feature).
Thanks to Intellij I can easily choose which library I want to include in the jar or not, (for instance the scala stl).
IMHO, this is by far the simplest method to get an executable jar for your project.
If you put the scala stl you can run your jar with the "java -jar" command, if you don't you have to run it somewhere with the correct version of scala installed with "scala".

Resources