I´m implementing a library in Kotlin that it will be used from Java.
It would be possible to create an annotation and AOP code in Kotlin, and then being used from Java.+
If that possible a documentation or example it would be awesome. I cannot find anything with that interoperability.
Regards.
As for the annotation, there should not be any problem implementing it in Kotlin.
As for the aspect, when compiled with the Kotlin compiler it shall end up being a regular JVM class with all the necessary #AspectJ annotations, but it will not be an aspect because it was not compiled by the AspectJ compiler which as of today only understands Java source code.
If you use such an "unfinished" aspect via LTW (load-time weaving), the AspectJ weaver can finish it into an aspect while it is being loaded, so that scenario should work.
In the case of trying to use the unfinished aspect for compile-time or binary weaving against Java (or Kotlin) target classes, an intermediate step to finish the unfinished aspect using the AspectJ compiler would be necessary, but I never tried that and do not know if it is even possible. It would be interesting to try. I do not speak Kotlin, but maybe it would be fun to try if you have something for me to start with like a sample project, ideally built with Maven. If there is any way to pull this off, we would end up using the AspectJ Maven plugin for just like #dreamcrash suggested, just in a different way.
BTW, I need more information from you about what you mean by "use from Java". Please elaborate.
Update: I just gave it a quick try:
Annotation + aspect both in Kotlin
Compile with Kotlin compiler into my-aspect.jar, aspectjrt.jar on the class path
Package Kotlin classes into a JAR
Java class using annotation from Kotlin aspect JAR
Compile with ajc, my-aspect.jar on the inpath and aspectjrt.jar and kotlin-stdlib.jar on the class path.
Result is e.g. in bin directory, both the Java class and the two Kotlin classes from the JAR, but the aspect this time finished by ajc (bigger class file than original).
Run Java program with bin folder, aspectjrt.jar and kotlin-stdlib.jar on the class path.
Works nicely, aspect kicks in.
The only step remaining is to "mavenise" this in connection with AspectJ Maven plugin, which should be fairly easy. But the answer to your question is: Yes, you can implement an aspect in Kotlin and use it combined with Java target classes. The downside of course is that you need the Kotlin standard library on the class path, not just the AspectJ runtime as usual.
Update 2: I created a Maven multi-module playground project for myself and for your convenience. Just clone my GitHub repository, then build and run according to the read-me file.
Related
As far as I understand, Lombok uses Java's Annotation Processors to generate additional methods.
With Maven 3.5 it works perfectly without adding any additional configuration, just add dependecy to Lombok and put some annotations like #Getter, #Setter.
However, if I open this project in IntelliJ IDEA 2018.2, all usages of generated getters/setters are highlighted as errors. I have Annotation Processing turned on, I tried to built project in IntelliJ or build in Maven and then use in IntelliJ, but it still requires Lombok Plugin to avoid false errors.
Is it some kind of bug? Error in workflow? Or maybe Lombok is using not only Annotation Processors, but some other stuff I didn't know and that's why IntelliJ + javac cannot figure out how to deal with it? It would be strange as javac itself compiles those files without errors
I know there are many questions "I have errors while using Lombok" and answers like "use the plugin". I'm not asking if I should use plugin, but why I should use it, why IntelliJ cannot handle it without plugin while javac does
IntelliJ's code analysis engine does not use javac or run annotation processors. Instead, IntelliJ uses its own Java parser and reference resolution logic, and builds its own code model. The Lombok plugin extends the code model to provide information about declarations generated by the Lombok annotation processor.
It's because IDEA syntax highlighter uses internal Java parser. If IDEA used just javac, then it wouldn't be able to highlight syntax errors as you type. It also gives much better hints about wrong code, so each Java construct, feature or annotation must be implemented by JetBrains team or there's plugin for it like in this case.
Annotation processing option is just for building project which is done via javac, but it's not for syntax highlighting.
Ale IDEs use lombok plugin be it intelij-idea or eclipse.
javac works fine with it - but remember that it works when for example you build you project with mvn clean package.
Then when you have your IDE - it works differntly - the code is not processed like in build task.
The plugin make it know to IDE what is this annotation and what code it generates underhood without need of javac.
I am trying to understand how Aspect works. I come from a C/C++ background where magic never happens.
I understand that you can annotate some functions with #Aspect then write down the Aspect implementation and so on. But, how (and at what time) does the new code get generated?
Assuming I have no editor. I compile java classes using javacc command
that will generate .class files. Now, assume that the java files are annotated using Aspect. Shouldn't I then compile the .class files again with Aspect somehow to generate another set of .class files?
If my understanding is correct, how is this dual compilation step done in maven? or spring? I found many tutorial that will tell you what to add here and there to get things working but no tutorial explains how these things are actually working.
It is easy to tell that you are a C++ guy. There is no such thing as javacc (if you are not talking about the Java Parser Generator of the same name) but the Java Compiler is called javac. ;-)
As Philipp Wendler already pointed out, Eclipse is not just an IDE, it is an organisation similar to Apache, and AspectJ has been adopted many years ago as one of its projects. This has also the advantage that AJDT (AspectJ Development Tools) for Eclipse IDE are sort of the best AspectJ support you can get for any IDE, sadly including my favourite IntelliJ IDEA which is superior to Eclipse IDE in almost all respects except its AspectJ support being rather mediocre.
So much for the minor topics. Now as for your main question, it is not really suited for Stack Overflow because it is rather a forum question, not about a concrete programming problem requiring a solution. Anyway, I love AspectJ and will answer briefly:
AspectJ has its own compiler ajc which is basically an enhanced version of the Eclipse Java Compiler ejc, i.e. it can be used to compile normal Java files as well as aspects in native AspectJ syntax or in #AspectJ style annotation-based syntax. No matter which way you weave your aspects, e.g.
build aspect + Java code with ajc from scratch (compile-time weaving),
build only aspects with ajc and Java code with javac, ejc or any other Java compiler, then
weave aspects into Java class files via ajc (post-compile or binary weaving) or
weave aspects into Java class files at runtime during class-loading with a Java agent called the AspectJ Weaver (load-time weaving, LTW),
What AspectJ does is always pretty much the same: It modifies Java byte code by weaving aspect code into it. In case 1 you just get one set of class files directly from ajc. Case 2.1 creates additional, new class files. Case 2.2 just creates new byte code in memory directly in the JVM.
Is there a way (built-in or via plugin) to restrict access to a Java package from other packages in Eclipse?
Example:
Packages (in same project):
com.my.project.common
com.my.project.serviceV1
com.my.project.serviceV2
Now I want to restrict access to serviceV1 and serviceV2 from common. But of course those services should be allowed to access the common package
Edit: If all you are looking for is simple package level protection that can be achieved using the private/protected/public/default package scopes, then I agree with the comment from #AlexisPigeon - that's the simplest route. Otherwise, I would consider the jdepend solution I proposed below.
No, this is not possible. I recommend looking at JDepend. It can produce a report of the package dependencies. You could write a script to parse the output and then fail your build (there are jdepend plugins for maven, ant and gradle) if one of your dependency constraints are violated.
My goal is to "read" the Java classes of a certain package, then to process the Javadoc and annotations (preferably at the same time) on the classes within that package and on the methods within those classes. Solution must be implemented in Java 6 or 7, build tool is Maven 3. We're currently using the maven-compiler-plugin, version 2.5.1, but I can probably upgrade that further if available/necessary.
As I understand it, the purpose of the javax.annotation.processing classes are to do this kind of thing, and I believe Java code along the lines of this other SO answer should work for my purposes, but the practical details of how to get it actually running are still a little fuzzy.
All that being said, here's what I think I need:
Java code to pick out the annotations and Javadoc items that I want, and then convert those items into the data model needed to create my custom documentation.
Java code to then write this data model out to a docs file or directory of files
Maven 3 configuration to:
Run the annotation processor once at a good time
Include the generated docs directory in the outputted war file
The Maven bits trip me up more than the Java code, so if you're only going to answer half, that's the half that'll get my check mark. Also, my preference would be to not put this annotation processor into a Maven repository as a separate plugin since it will be very tightly coupled with some custom annotations we're using.
Here's a brief listing of questions that I found as related from which I could not synthesize my own answer, though:
Writing an annotation processor for maven-processor-plugin
Maven annotation processing with maven-compiler-plugin
How to configure the Annotation Processing API without external Jar using Maven?
Can the Pluggable Annotation Processor API retrieve source code comments?
I'm not sure if you can access the Javadoc from annotation processors. Consider to use the Doclet API:
http://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/doclet/overview.html
Edit:
Here is an annotation processor I wrote. Maybe it can serve as a sample:
http://softsmithy.hg.sourceforge.net/hgweb/softsmithy/lib/main-golden/file/ae786193023d/softsmithy-lib-core/src/main/java/org/softsmithy/lib/util/impl/ServiceProviderAnnotationProcessor.java
http://softsmithy.hg.sourceforge.net/hgweb/softsmithy/lib/main-golden/file/ae786193023d/softsmithy-lib-core/pom.xml
http://softsmithy.hg.sourceforge.net/hgweb/softsmithy/softsmithy-parent/main-golden/file/9397853ba514/pom.xml
For Maven: as far as I can remember you have to pass -proc:none as compiler argument (compiler plugin) in the project that contains the annotation processor. In that project also add the following resource file: META-INF/services/javax.annotation.processing.Processor and add the fully qualified name of your annotation processor in the first line.
I usually package the annotation, the annotation processor and this "service registry file" in the same project A. Then in any other project B where I'm using the annotation and thus have a dependency on this project A, the annotation processor is picked up automatically.
I'm using the Maven Compiler Plugin v2.3.2 and Java SE 7.
I am new to java and to netbeans so my apologies if this is a simple question.
I made a 'Java Class Library' Project in Netbeans 6.9.1
I added a few classes to it and hit 'Build'. It builds with no errors. However the problem is I know there are errors.
It seems as though I can make up class names and hit build and it doesnt provide me with any feedback.
How can I make it so that netbeans validates my code when buildling a class library?
I am unable to 'run' the project becuase there is no Main. However this is a class library and I dont want to make test applications in my library.
Edit:
For example I can write the following and a 'clean & build' still works
MadeUpName x = new MadeUpName();
This will build even though I have no class or reference to a class that contains
MadeUpName
I also have no 'Import' statments as of yet and it still builds....
Thanks, stephanie
1) To test a Java Class Library project you should create another project and add your "Java Class Library" project as project dependency. In this new testing project you can write class with main method to test features of the class library. When you will build the test project NetBeans IDE will also build the class library project and will add the JAR file in the class path of the testing project.
2) If the Java Class Library projects compiles through "Clean & Build" that means the project has no syntax errors. That means your code may have logical errors which are not detected by the Java compiler. Usually class library developers create JUnit test cases to find out logical errors, and you are also strongly advised to use JUnit tests for your project.
with regards
Tushar Joshi, Nagpur
Ideally you should test a class library by writing unit tests (rather than test applications) that exercise the classes in your library. There are several unit-testing frameworks available that can help you write the unit tests. The most popular is JUnit.
The test cases should be placed in a different source folder in the same project as the code they are testing. When you build the project you should ensure that the test classes are not included in the JAR file. If you use a build tool like Maven it will do this for you as long as you follow it's project conventions.
Update
Based on your comments, and the fact that you tagged your question with Groovy, I'm guessing that the library is written in Groovy? Your problem seems to be that Netbeans doesn't perform the kind of type-checking that you get with Java (or other statically-typed languages)?
Because Groovy is a dynamic language, it's not possible for the compiler to perform the same rigorous type-checking that you get with Java, but at the very least the Netbeans Groovy editor should provide some hints/warnings if you're referencing classes that don't exist (for example). Are you sure you're opening the code in the correct editor (you may need to install a Groovy plugin first).
You should use GroovyTestCase, rather than JUnit directly to test a Groovy library.