I am trying to work with Scala and AspectJ on IntelliJ as the IDE. #The file structure
Sample.scala - (The class which consists of the main method)
package sample
class SampleClass {
def printSample():Unit = println("hello")
}
object SampleObject extends App {
val sample = new SampleClass
sample.printSample()
}
Tracer.scala - (The Tracer function or in other words the aspect)
package sample
import org.aspectj.lang.annotation._
@Aspect
class Tracer {
@Before("execution(* sample.SampleClass.printSample(..))")
def printSample() {
println("Printing sample:")
}
}
build.sbt - in order to run the sbt command(sbt compile and sbt run)
name := "testingAspectScalaFullexample"
version := "0.1"
scalaVersion := "2.13.5"
lazy val buildSettings = Seq(
organization := "com.lightbend.sbt.aspectj",
version := "0.1-SNAPSHOT",
scalaVersion := "2.12.1"
)
lazy val sample = (project in file("."))
.settings(buildSettings)
.aggregate(tracer, instrumented)
// precompiled aspects
lazy val tracer = (project in file("tracer"))
.enablePlugins(SbtAspectj)
.settings(buildSettings)
.settings(
// input compiled scala classes
aspectjInputs in Aspectj += (aspectjCompiledClasses in Aspectj).value,
// ignore warnings
aspectjLintProperties in Aspectj += "invalidAbsoluteTypeName = ignore",
aspectjLintProperties in Aspectj += "adviceDidNotMatch = ignore",
// replace regular products with compiled aspects
products in Compile := (products in Aspectj).value
)
// test that the instrumentation works
lazy val instrumented = (project in file("instrumented"))
.enablePlugins(SbtAspectj)
.settings(buildSettings)
.settings(
// add the compiled aspects from tracer
aspectjBinaries in Aspectj ++= (products in Compile in tracer).value,
// weave this project's classes
aspectjInputs in Aspectj += (aspectjCompiledClasses in Aspectj).value,
products in Compile := (products in Aspectj).value,
products in Runtime := (products in Compile).value
).dependsOn(tracer)
// for sbt scripted test:
TaskKey[Unit]("check") := {
import scala.sys.process.Process
val cp = (fullClasspath in Compile in instrumented).value
val mc = (mainClass in Compile in instrumented).value
val opts = (javaOptions in run in Compile in instrumented).value
val expected = "Printing sample:\nhello\n"
val output = Process("java", opts ++ Seq("-classpath", cp.files.absString, mc getOrElse "")).!!
if (output != expected) {
println("Unexpected output:")
println(output)
println("Expected:")
println(expected)
sys.error("Unexpected output")
} else {
print(output)
}
}
However when I run sbt compile, this error crops up:
Weaving 1 input to ,<path>\SpringIn28Minutes-master\SpringIn28Minutes-master\testingAspectScalaFullexample\tracer\target\scala-2.12\aspectj\classes...
[error] error can't determine superclass of missing type java.lang.Object
[error] when batch building BuildConfig[null] #Files=0 AopXmls=#0
[error] [Xlint:cantFindType]
[error] org.aspectj.bridge.AbortException: AspectJ failed
[error] at com.lightbend.sbt.SbtAspectj$Ajc$.runAjcMain(SbtAspectj.scala:212)
[error] at com.lightbend.sbt.SbtAspectj$Ajc$.runAjc(SbtAspectj.scala:124)
[error] at com.lightbend.sbt.SbtAspectj$Ajc$.$anonfun$ajcTask$2(SbtAspectj.scala:111)
[error] at sbt.util.FileFunction$.$anonfun$cached$1(FileFunction.scala:80)
[error] at sbt.util.FileFunction$.$anonfun$cached$4(FileFunction.scala:153)
[error] at sbt.util.Difference.apply(Tracked.scala:414)
[error] at sbt.util.Difference.apply(Tracked.scala:394)
[error] at sbt.util.FileFunction$.$anonfun$cached$3(FileFunction.scala:149)
[error] at sbt.util.Difference.apply(Tracked.scala:414)
[error] at sbt.util.Difference.apply(Tracked.scala:389)
[error] at sbt.util.FileFunction$.$anonfun$cached$2(FileFunction.scala:148)
[error] at com.lightbend.sbt.SbtAspectj$Ajc$.$anonfun$ajcTask$1(SbtAspectj.scala:116)
[error] at scala.Function1.$anonfun$compose$1(Function1.scala:49)
[error] at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:62)
[error] at sbt.std.Transform$$anon$4.work(Transform.scala:68)
[error] at sbt.Execute.$anonfun$submit$2(Execute.scala:282)
[error] at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:23)
[error] at sbt.Execute.work(Execute.scala:291)
[error] at sbt.Execute.$anonfun$submit$1(Execute.scala:282)
[error] at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:265)
[error] at sbt.CompletionService$$anon$2.call(CompletionService.scala:64)
[error] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[error] at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executo
rs.java:515)
[error] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[error] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoo
lExecutor.java:1130)
[error] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPo
olExecutor.java:630)
[error] at java.base/java.lang.Thread.run(Thread.java:831)
[error] (tracer / Aspectj / ajc) org.aspectj.bridge.AbortException: AspectJ failed
OK, you are using this example from the plugin source code repository. Why didn't you just say so and link to it? You made it look as if you created the sample by yourself. I found it and also the project/plugins.sbt
which you did not post here. Like I told you before in our chat, I am a Scala noob, I never used it in my whole life and had no idea that a file was missing. That cost me a lot of time. Why did you post an incomplete sample project here instead of publishing it on GitHub like I asked you to? Then I could just have cloned the project and run it. Not until I found the sample code online, did I realise that yours was incomplete.
Furthermore, my IDE IntelliJ IDEA cannot import the sample project, there must be some kind of bug in the current version. I can only compile and run from sbt shell. There, I could finally reproduce your problem.
Actually, the explanation is quite simple: The plugin is outdated and ought to be updated ASAP. It depends on AspectJ Compiler Tools 1.8.10 which only supports Java 8. It is not even the most recent 1.8 release, that should be 1.8.13. Also, the plugin exports AspectJ Runtime 1.8.10 as a runtime dependency to projects using the plugin. See also:
As long as you compile and run your project on JDK 1.8, everything is fine. If you use a more recent JDK, the solution is to override the dependencies. Put this into project/plugins.sbt
:
addSbtPlugin("org.jetbrains" % "sbt-ide-settings" % "1.1.0")
addSbtPlugin("com.lightbend.sbt" % "sbt-aspectj" % "0.11.0")
dependencyOverrides += "org.aspectj" % "aspectjrt" % "1.9.6"
dependencyOverrides += "org.aspectj" % "aspectjtools" % "1.9.6"
AspectJ 1.9.6 supports up to language level 14. Version 1.9.7 supporting Java 15+16 will be released soon. But if you run on JDK 16, but compile to no higher than target 14, you should be fine.
BTW, the test is platform-specific and will fail on Windows because there it expects UNIX line separators (LF), while Windows uses CR+LF:
val expected = "Printing sample:\nhello\n"
You should change that to:
val LF = System.lineSeparator()
val expected = "Printing sample:" + LF + "hello" + LF