AspectJ compiler (ajc) vs load-time weaving - aspectj

Several questions here:
Does ajc change all the classes it compiles (even non-aspect ones)? What if I compile only aspect classes ant then put them in the same classpath with the common ones?
Does the ajc-compiled project perform faster then the one that uses load-time weaving?
What if I need to write a library, that does tracing with AspectJ, and then I want this library to work with ANY project? Is load-time weaving the only option in this case?

ajc (compile time) will only change classes that are affected by aspects. Remember, ajc is an extension of a Java compiler (to be precise, it is based on Eclipse 3.3's JDT compiler). So, it will compile all your Java classes as would a normal Java compiler. It will then additionally weave all classes that are affected by an aspect. If you compile your aspects separately from your non-aspects then there will be no compile time weaving going on and your aspects will not have any affect. However, you can put your aspects on the aspect path of the compilation of your non-aspects (if your non-aspects are compiled by ajc). This will allow your non-aspects to be woven by your aspects.
Start-up time under CTW is much better than LTW, but after all classes are loaded, speed difference should be negligible. The reason is that under LTW, all classes are woven when they are loaded. This means that classloading requires the additional step of weaving which is not necessary under CTW.
No. As mentioned above, you can add the aspects to your aspect path of the second project, and then they will be woven during compilation.
More on Aspect path:
http://www.eclipse.org/aspectj/doc/released/devguide/ajc-ref.html

Related

Is it good to upgrade to MapStruct from ModelMapper?

Currently we are using ModelMapper in our project. However in the site i see there are lot of likes for MapStruct.
Not sure the differences and whether we need to really go for an upgrade.
What are the differences between ModelMapper and MapStruct ?
Thanks.
(Project lead of MapStruct here, so naturally I am biased)
I have not used ModelMapper before. However, the projects are quite different in the way they are doing the mapping. I believe that ModelMapper is based on reflection and performs the mapping during runtime. Whereas MapStruct is a code generator which generates the mapping code (java classes) during compilation time.
So naturally if you are worried about performance then MapStruct is the clear choice. There is this independent Java Object Mapper Benchmark that benchmarks different frameworks.
The code that is generated by MapStruct is human readable code which is easy to debug and there is no reflection in it.
There are a lot of built-in conversions.
You get notified during compilation time if something could not be mapped and you would be responsible to providing such mappings so MapStruct can use them.
There are also IDE plugins:
* IntelliJ plug-in: helps when editing mapper interfaces via auto-completion, go to referenced properties, refactoring support etc.
* Eclipse plug-in avaible: has quickfixes and auto-completions which are very helpful when designing mapper interfaces

How to convert aspect java (.aj) to .java?

I thought ever it could be very nice, if the weaving and the actual compilation happened in different steps. Is there any not-really-well-known flag, or some such alternate solution to generate the intermediate .java code?
Anyways, weaving happens on the classes, or on the java source?
Weaving happens on the bytecode.
You might be able to disassemble the resulting bytecode, though.
Dave is right that weaving happens on bytecode (been that way since version 1.2). But you are still able to compile things separately and do weaving later. Build your regular java code as normal into a jar, then build your aspects into an aspect library, then just apply one to the other:
ajc -aspectpath myaspects.jar -inpath mycode.jar -outjar mywovencode.jar
Effectively that is compiling and weaving happening in different steps.

Macro project - macro in its own configuration

The SBT documentation about Macro Projects starts with the following:
The current macro implementation in the compiler requires that macro implementations be compiled before they are used. The solution is typically to put the macros in a subproject or in their own configuration.
What does exactly mean to put the macros "in their own configuration"? Does it mean there is an alternative to putting macro source in a subproject? If so, what would that alternative be? I'm looking for an option where I'd not have to separate macro source from invocations, mainly because I don't want yet another subproject for common code.
I believe the author refers to the Configuration scop. In short: you already know that diffrent sources can reside under src/main/scala and src/test/scala, and that code in the test configuration can use code from the compile (main) configuration. so why not having a custom configuration, e.g. macro, and sources for it can reside under src/macro/scala?
there's a great answer on this matter, I suggest you take a look.
also, you could find useful examples here. it's an explanation on defining new configurations for tests. but you could exploit it for your needs.
I don't know what the author meant by own configuration.
An alternative is to use SBT's ability to generate sources (c.f. sourceGenerators) before they get compiled. "Generating" in fact allows you for instance to copy macro source files from elsewhere.
However that's convoluted, so I'd recommend to separate macros in a sub-project. Besides, separating macros still allows you to build even if you switch to an IDE that doesn't support SBT (then you have a macro-defining project and a macro-using project).

AspectJ compile-time weaving and Scala

Is it possible to have a Scala Maven project and weave AspectJ aspects at compile-time within the Scala classes?
I've been able to get load-time weaving to work but so far no success with compile-time.
The aspects are simply not woven into the Scala classes. From what I understand, compile-time weaving requires a specific Java compiler (AspectJ Compiler aka ajc). It is my understanding that ajc cannot compile Scala.
Is there an ajc equivalent for Scala? Or perhaps another way to get compile-time weaving to work with Scala?
Answer 1 isn't true compile-time weaving - it's binary weaving of already-compiled classes. It wouldn't work, for instance, if your scala classes needed the aspects to compile properly. I think the issue of compile-time weaving in scala is still an open question.
We agree with the assessment by the original poster that ajc is unlikely to know how to compile scala.
How about using AJC's -inpath switch? It accepts .class files in directories or JARs and weaves into them. Your Scala compiles to .class files, so that ought to work. No doubt you have the AJC docs, but here's a link.

intellij idea 11, scala slow execution [duplicate]

I've been programming in Scala for a while and I like it but one thing I'm annoyed by is the time it takes to compile programs. It's seems like a small thing but with Java I could make small changes to my program, click the run button in netbeans, and BOOM, it's running, and over time compiling in scala seems to consume a lot of time. I hear that with many large projects a scripting language becomes very important because of the time compiling takes, a need that I didn't see arising when I was using Java.
But I'm coming from Java which as I understand it, is faster than any other compiled language, and is fast because of the reasons I switched to Scala(It's a very simple language).
So I wanted to ask, can I make Scala compile faster and will scalac ever be as fast as javac.
There are two aspects to the (lack of) speed for the Scala compiler.
Greater startup overhead
Scalac itself consists of a LOT of classes which have to be loaded and jit-compiled
Scalac has to search the classpath for all root packages and files. Depending on the size of your classpath this can take one to three extra seconds.
Overall, expect a startup overhead of scalac of 4-8 seconds, longer if you run it the first time so disk-caches are not filled.
Scala's answer to startup overhead is to either use fsc or to do continuous building with sbt. IntelliJ needs to be configured to use either option, otherwise its overhead even for small files is unreasonably large.
Slower compilation speed. Scalac manages about 500 up to 1000 lines/sec. Javac manages about 10 times that. There are several reasons for this.
Type inference is costly, in particular if it involves implicit search.
Scalac has to do type checking twice; once according to Scala's rules and a second time after erasure according to Java's rules.
Besides type checking there are about 15 transformation steps to go from Scala to Java, which all take time.
Scala typically generates many more classes per given file size than Java, in particular if functional idioms are heavily used. Bytecode generation and class writing takes time.
On the other hand, a 1000 line Scala program might correspond to a 2-3K line Java program, so some of the slower speed when counted in lines per second has to balanced against more functionality per line.
We are working on speed improvements (for instance by generating class files in parallel), but one cannot expect miracles on this front. Scalac will never be as fast as javac.
I believe the solution will lie in compile servers like fsc in conjunction with good dependency analysis so that only the minimal set of files has to be recompiled. We are working on that, too.
The Scala compiler is more sophisticated than Java's, providing type inference, implicit conversion, and a much more powerful type system. These features don't come for free, so I wouldn't expect scalac to ever be as fast as javac. This reflects a trade-off between the programmer doing the work and the compiler doing the work.
That said, compile times have already improved noticeably going from Scala 2.7 to Scala 2.8, and I expect the improvements to continue now that the dust has settled on 2.8. This page documents some of the ongoing efforts and ideas to improve the performance of the Scala compiler.
Martin Odersky provides much more detail in his answer.
You should be aware that Scala compilation takes at least an order of magnitude longer than Java to compile. The reasons for this are as follows:
Naming conventions (a file XY.scala file need not contain a class called XY and may contain multiple top-level classes). The compiler may therefore have to search more source files to find a given class/trait/object identifier.
Implicits - heavy use of implicits means the compiler needs to search any in-scope implicit conversion for a given method and rank them to find the "right" one. (i.e. the compiler has a massively-increased search domain when locating a method.)
The type system - the scala type system is way more complicated than Java's and hence takes more CPU time.
Type inference - type inference is computationally expensive and a job that javac does not need to do at all
scalac includes an 8-bit simulator of a fully armed and operational battle station, viewable using the magic key combination CTRL-ALT-F12 during the GenICode compilation phase.
The best way to do Scala is with IDEA and SBT. Set up an elementary SBT project (which it'll do for you, if you like) and run it in automatic compile mode (command ~compile) and when you save your project, SBT will recompile it.
You can also use the SBT plug-in for IDEA and attach an SBT action to each of your Run Configurations. The SBT plug-in also gives you an interactive SBT console within IDEA.
Either way (SBT running externally or SBT plug-in), SBT stays running and thus all the classes used in building your project get "warmed up" and JIT-ed and the start-up overhead is eliminated. Additionally, SBT compiles only source files that need it. It is by far the most efficient way to build Scala programs.
The latest revisions of Scala-IDE (Eclipse) are much better atmanaging incremental compilation.
See "What’s the best Scala build system?" for more.
The other solution is to integrate fsc - Fast offline compiler for the Scala 2 language - (as illustrated in this blog post) as a builder in your IDE.
But not in directly Eclipse though, as Daniel Spiewak mentions in the comments:
You shouldn't be using FSC within Eclipse directly, if only because Eclipse is already using FSC under the surface.
FSC is basically a thin layer on top of the resident compiler which is precisely the mechanism used by Eclipse to compile Scala projects.
Finally, as Jackson Davis reminds me in the comments:
sbt (Simple build Tool) also include some kind of "incremental" compilation (through triggered execution), even though it is not perfect, and enhanced incremental compilation is in the work for the upcoming 0.9 sbt version.
Use fsc - it is a fast scala compiler that sits as a background task and does not need loading all the time. It can reuse previous compiler instance.
I'm not sure if Netbeans scala plugin supports fsc (documentation says so), but I couldn't make it work. Try nightly builds of the plugin.
You can use the JRebel plugin which is free for Scala. So you can kind of "develop in the debugger" and JRebel would always reload the changed class on the spot.
I read some statement somewhere by Martin Odersky himself where he is saying that the searches for implicits (the compiler must make sure there is not more than one single implicit for the same conversion to rule out ambiguities) can keep the compiler busy. So it might be a good idea to handle implicits with care.
If it doesn't have to be 100% Scala, but also something similar, you might give Kotlin a try.
-- Oliver
I'm sure this will be down-voted, but extremely rapid turn-around is not always conducive to quality or productivity.
Take time to think more carefully and execute fewer development micro-cycles. Good Scala code is denser and more essential (i.e., free from incidental details and complexity). It demands more thought and that takes time (at least at first). You can progress well with fewer code / test / debug cycles that are individually a little longer and still improve your productivity and the quality of your work.
In short: Seek an optimum working pattern better suited to Scala.