I can't figure out how to do benchmarks of Scala programs in Intellij with JMH.
Here's what I've done so far:
Added the JMH SBT-Plugin
// build.sbt
name := "Project"
version := "1.0"
scalaVersion := "2.11.8"
enablePlugins(JmhPlugin)
// project/plugins.sbt
logLevel := Level.Warn
addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.2.10")
Here is the plugin's website
Created a benchmark class
// src/main/scala/MyBenchmark.scala
import org.openjdk.jmh.annotations.Benchmark
class MyBenchmark {
#Benchmark
def test(): Unit = println("test")
}
Created an SBT-Task in Intellij
But after running the task I just get an exception:
Annotation generator had thrown the exception.
java.lang.NullPointerException
at org.openjdk.jmh.generators.reflection.RFClassInfo.getPackageName(RFClassInfo.java:51)
at org.openjdk.jmh.generators.core.BenchmarkGenerator.validateBenchmark(BenchmarkGenerator.java:243)
at org.openjdk.jmh.generators.core.BenchmarkGenerator.generate(BenchmarkGenerator.java:90)
....
What am I doing wrong?
Try to add package name in the benchmark class.
Because JMH is complaining about package name is not found.
org.openjdk.jmh.generators.reflection.RFClassInfo.getPackageName(RFClassInfo.java:51)
you should add the line like:
package your.path;
Related
I want to create a sbt plugin
this is my project
build.sbt file:
lazy val root = (project in file(".")).
settings(
name := "test-plagin",
version := "0.1.0",
organization := "com.test",
scalaVersion := "2.13.0",
sbtPlugin := true,
)
main file with task
import sbt.{AutoPlugin, TaskKey}
object HelloPlugin extends AutoPlugin {
object autoImport {
val sayHello: TaskKey[Unit] = TaskKey("saying hello")
}
import autoImport._
override def projectSettings = Seq(
sayHello := {
println("hello")
}
)
}
During compiling I get an error:
java.lang.NoClassDefFoundError: scala/collection/immutable/StringOps
When I change the version to 2.12.6 - compiling is success.
How I can fix error in 2.13?
sbt is written in Scala 2.12
https://github.com/sbt/sbt/blob/develop/project/Dependencies.scala#L9
https://github.com/sbt/sbt/issues/5032
So you should use Scala 2.12 for sbt plugins.
I am new to Scala and I am trying to develop a small project which uses a custom library. I have created a mysql connection pool inside the library. Here's my build.sbt for library
organization := "com.learn"
name := "liblearn-scala"
version := "0.1"
scalaVersion := "2.12.6"
libraryDependencies += "mysql" % "mysql-connector-java" % "6.0.6"
libraryDependencies += "org.apache.tomcat" % "tomcat-dbcp" % "8.5.0"
I have published the same to local ivy repo using sbt publishLocal
Now I have a project which will be making use of the above library with following build.sbt
name := "SBT1"
version := "0.1"
scalaVersion := "2.12.6"
libraryDependencies += "com.learn" % "liblearn-scala_2.12" % "0.1"
I am able to compile the new project but when I run it I get
java.lang.ClassNotFoundException: org.apache.tomcat.dbcp.dbcp2.BasicDataSource
But if I add
libraryDependencies += "mysql" % "mysql-connector-java" % "6.0.6"
libraryDependencies += "org.apache.tomcat" % "tomcat-dbcp" % "8.5.0"
in the project's build.sbt it works without any issues.
Is this the actual way of doing things with scala - sbt? ie : I have to mention dependencies of custom library also inside the project?
Here is my library code (I have just 1 file)
package com.learn.scala.db
import java.sql.Connection
import org.apache.tomcat.dbcp.dbcp2._
object MyMySQL {
private val dbUrl = s"jdbc:mysql://localhost:3306/school?autoReconnect=true"
private val connectionPool = new BasicDataSource()
connectionPool.setUsername("root")
connectionPool.setPassword("xyz")
connectionPool.setDriverClassName("com.mysql.cj.jdbc.Driver")
connectionPool.setUrl(dbUrl)
connectionPool.setInitialSize(3)
def getConnection: Connection = connectionPool.getConnection
}
This is my project code:
try {
val conn = MyMySQL.getConnection
val ps = conn.prepareStatement("select * from school")
val rs = ps.executeQuery()
while (rs.next()) {
print(rs.getString("name"))
print(rs.getString("rank"))
println("----------------------------------")
}
rs.close()
ps.close()
conn.close()
} catch {
case ex: Exception => {
println(ex.printStackTrace())
}
}
By default SBT fetches all project dependencies, transitively. This means it should be necessary to explicitly declare only liblearn-scala, and not also the transitive dependencies mysql-connector-java and tomcat-dbcp. Transitivity can be disabled, and transitive dependencies can be excluded, however unless this has been done explicitly, then it should not be the cause of the problem.
Without seeing your whole build.sbt, I believe you are doing the right thing. If sbt clean publishLocal is not solving the problem, you could try the nuclear option and clear the whole ivy cache (note this will force all projects to re-fetch dependencies).
I'm trying to workaround creating sbt AutoPlugins.
I want to create plugin which will autoloading all his dependencies, so I use NoTrigger policy.
I wrote my own AutoPlugin which must execute assembly task from sbt-assembly and look like:
settings in /build.sbt
name := "sbt-myplugin"
version := "0.0.1"
organization := "com.org"
scalaVersion := "2.10.6"
sbtPlugin := true
sbtVersion := "0.13.11"
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.3")
plugin code in /src/main/scala/myplugin/MyPlugin.scala
package myplugin
import sbt._
import sbtassembly.AssemblyPlugin
import sbtassembly.AssemblyPlugin.autoImport._
object MyPlugin extends AutoPlugin{
override def trigger = noTrigger
override def requires = AssemblyPlugin
object autoImport {
val myAssembly = taskKey[File]("Assembled file")
}
import autoImport._
override lazy val projectSettings = Seq(
myAssembly := assembly.value
)
}
Then i'm create artifact with sbt clean compile publishLocal
After this I created test project which will use my plugin.
settings for this project in /project/plugins.sbt
logLevel := Level.Warn
resolvers += "Local Ivy Repository" at "file://"+Path.userHome.absolutePath+"/.ivy2/local"
addSbtPlugin("com.academmedia.ias" % "sbt-pkplace" % "0.0.1")
settings in /biuld.sbt
name := "test-project"
version := "1.0"
scalaVersion := "2.11.8"
lazy val root = (project in file(".")).enablePlugins(myplugin.MyPlugin)
Now I'm expecting able to use MyPlugin task myAssembly but my project sbt is unable to download project settings with error:
[error] java.lang.NoClassDefFoundError: sbtassembly/AssemblyPlugin$
What am I doing wrong?
Thanks for answer!
I have used specs2 many times successfully in vanilla SBT projects. now I am starting to learn typesafe activator platform.
I did the following steps
activator new Shop just-play-scala
this is my build.sbt file
name := """Shop"""
version := "1.0-SNAPSHOT"
// Read here for optional jars and dependencies
libraryDependencies ++= Seq("org.specs2" %% "specs2-core" % "3.6.1" % "test")
resolvers += "scalaz-bintray" at "http://dl.bintray.com/scalaz/releases"
scalacOptions in Test ++= Seq("-Yrangepos")
lazy val root = project.in(file(".")).enablePlugins(PlayScala)
I created a file Shop/app/test/models/ShopSpec.scala
import org.specs2.mutable.Specification
class ShopSpec extends Specification {
def foo = s2"""
| This is a specification to check the 'Hello world' string
| The 'Hello world' string should
| contain 11 characters $e1
| start with 'Hello' $e2
| end with 'world' $e3
| """.stripMargin
def e1 = "Hello world" must haveSize(11)
def e2 = "Hello world" must startWith("Hello")
def e3 = "Hello world" must endWith("world")
}
When I run activator test I get an error
[success] Total time: 0 s, completed Jun 24, 2015 12:21:32 AM
Mohitas-MBP:Shop abhi$ activator test
[info] Loading project definition from /Users/abhi/ScalaProjects/Shop/project
[info] Set current project to Shop (in build file:/Users/abhi/ScalaProjects/Shop/)
**cannot create a JUnit XML printer. Please check that specs2-junit.jar is on the classpath**
org.specs2.reporter.JUnitXmlPrinter$
java.net.URLClassLoader.findClass(URLClassLoader.java:381)
java.lang.ClassLoader.loadClass(ClassLoader.java:424)
sun.misc.Launcher$AppClassLoader.loadClass(Launcher.jav
I have previously written spec2 test cases successfully when I was using SBT projects. but only when I use the typesafe activator that I get this issue with test cases.
I even changed the code of my test to something as simple as
import org.specs2.mutable.Specification
class ShopSpec extends Specification {
"A shop " should {
"create item" in {
failure
}
}
}
But still the same problem.
Wait .. I think I resolved it.
The activator play platform already has specs2 included so there is no need for me to tweak the built.sbt file for specs 2.
So I removed everything I had added to build.sbt file and left the file as
name := """Shop"""
version := "1.0-SNAPSHOT"
lazy val root = project.in(file(".")).enablePlugins(PlayScala)
Now it works fine. So basically, I don't need to add anything in a activator project for specs2.
I could have deleted the question... but leaving it here so that it can be of help to someone.
What worked for me was adding the following to build.sbt:
libraryDependencies ++= Seq("org.specs2" %% "specs2-core" % "3.6.2" % "test",
"org.specs2" %% "specs2-junit" % "3.6.2" % "test")
There is a great sbt plugin sbt-dependency-graph, which provides a dependencyTree task to show the dependencies.
I want to write a sbt plugin which depends on it, but always fails.
build.sbt
sbtPlugin := true
name := "my-sbt-plugin-depends-on-another"
version := "0.1.2.1"
organization := "test20140913"
addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.7.5")
src/main/scala/MySbtPlugin.scala
import sbt._
object MySbtPlugin extends AutoPlugin {
object autoImport {
lazy val hello = taskKey[Unit]("hello task from my plugin")
lazy val hello2 = taskKey[Unit]("hello task from my plugin2")
}
import autoImport._
override def trigger = allRequirements
override def requires = plugins.JvmPlugin
val helloSetting = hello := println("Hello from my plugin")
val helloSetting2 = hello2 := {
println("hello2, task result from another plugins:")
println(net.virtualvoid.sbt.graph.Plugin.dependencyTree.value)
println("=========================================")
}
override def projectSettings = Seq(
helloSetting, helloSetting2
)
}
Then I published it to local, and use it in another project:
build.sbt
name := "sbt--plugin-test"
version := "1.0"
scalaVersion := "2.11.6"
net.virtualvoid.sbt.graph.Plugin.graphSettings
project/plugins.scala
logLevel := Level.Info
addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.7.5")
addSbtPlugin("test20140913" % "my-sbt-plugin-depends-on-another" % "0.1.2.1")
When I run sbt on the later project, it reports:
Reference to undefined setting:
*:dependencyTree from *:hello2 (/Users/twer/workspace/my-sbt-plugin-depends-on-another/src/main/scala/test20140913/MySbtPlugin.scala:38)
Did you mean provided:dependencyTree ?
at sbt.Init$class.Uninitialized(Settings.scala:262)
at sbt.Def$.Uninitialized(Def.scala:10)
at sbt.Init$class.delegate(Settings.scala:188)
at sbt.Def$.delegate(Def.scala:10)
Where is wrong?
PS: The plugin code is here: https://github.com/freewind/my-sbt-plugin-depends-on-another
dependencyTree is only defined for specific configurations (well all of them), but it automatically delegates to Compile in the shell.
Try defining hello2 like so:
val helloSetting2 = hello2 := {
println("hello2, task result from another plugins:")
import net.virtualvoid.sbt.graph.Plugin.dependencyTree
println((dependencyTree in Compile).value)
println("=========================================")
}