Is Eclipse's ecj compiler extensible? - java

I am interested in modifying Java syntax and some implicit paradigms. Since I develop with Eclipse which provides it's own compiler, which can also be used standalone, I was wondering if it wasn't possible to extend ecj to respect additional grammar rules (and correctly handle them).
My syntactical changes are all resolvable by removing elements from the AST and creating some new ones, so I assume that what I want to do is possible without diving into bytecode.
Essentially, what I want to do could be done by 'virtually' modifying the source code before the actual compilation. However I suspect that doing so would mess up the source mapping, which would make debugging a hell.
On a sidenote: I am aware of project Lombok, which extends and alters class compilation, however Lombok uses annotations only, and does not modify syntax, strictly speaking. So what I want to do is more invasive to the language specs.

As Object Teams has been mentioned in comments:
(1) Object Teams itself extends JDT for its own language OT/J which is an extension of Java. This is done in a dual strategy:
We maintain a fork of org.eclipse.jdt.core. While this is quite heavy lifting it successfully demonstrates that the JDT architecture is suitable for modification.
We use our own concepts of role objects to non-invasively adapt the behavior of other parts of the IDE (notably org.eclipse.jdt.ui) to reflect the semantics of OT/J
(2) I have a few (oldish) blog posts that demonstrate how OT/J can be used for creating non-invasive variants of JDT including support for extended syntax:
IDE for your own language embedded in Java? (part 1)
IDE for your own language embedded in Java? (part 2)
Get for free what Coin doesn’t buy you
Disclaimer: I am author of OT/J and lead of its implementation, and later became a committer on Eclipse JDT.
For further questions, there's a forum.

Related

Java Libraries Reuse

In software development we are all using the libraries by software providers. Consider in class A there are four functions viz., x,y,z. I just want my development team to avoid using the function x. So instead of telling them not to use, I found an idea. Inherit the class and override all the functions and for the function x an unsupportedmethod exception is thrown and for the rest I'm calling the super methods. There also I found a problem, developers can use the base class A directly, how to avoid the class A being used directly. I found a similar functionality in OSGi, the lib bundles can be brought in and then not exported and so on. Is there are any way to achieve this is java?
I suppose code reviews exist for these reasons. Consider situation where you can not edit the source of a third party, what would you do ? Like Siddharth says, sub class it and throw a meaningful exception and document it with a clear reasons. If someone is using base class even after that, mostly it may not out of ignorance,but it may out of curiosity. That kind of thing can be appreciated personally and for learning, but for the project sake developer has to follow the guidelines.
I think simply telling your developers what to do is preferred over a complex software solution. Sometimes the simple thing is better.
But, if you insist on going down this path, you can enforce your architecture standards using aspects if you're a Spring user. Weave the offending methods with an aspect that throws an exception if they're called.
You can edit library class file in hex editor and modify its access modifier from public to package private. Also you can rename it and then use inheritance to wrap this class. Here you can find class file specification. Once I've tried this technique to substitute jdbc driver class with wraper class that provide some additional logging and other useful tricks.
There is a variety of tools that check source code for adherence to certain rules, such as formatting, dead code, naming conventions for variables etc. Popular ones for Java include the Maven Enforcer plugin, checkstyle and PMD.
These might allow you to write a rule that forbids certain method calls. Then you could check automatically at compile time. As far as I can tell, unfortunately none of the tools above support "illegal method calls" out-of-the-box; however, at least for PMD writing new checks is fairly simple.

Ways to work around the lack of package access specifiers?

I'm new to Java. I've discovered, while trying to structure my code, that Java intimately ties source file organisation (directory structure) to package structure and package structure to external visibility of classes (a class is either visible to all other packages, or none).
This makes it quite difficult to organise the internal implementation details of my public library into logical units of related functionality while maintaining good encapsulation. JSR 294 explains it best:
Today, an implementation can be partitioned into multiple packages.
Subparts of such an implementation need to be more tightly coupled to
each other than to the surrounding software environment. Today
designers are forced to declare elements of the program that are
needed by other subparts of the implementation as public - thereby
making them globally accessible, which is clearly suboptimal.
Alternately, the entire implementation can be placed in a single
package. This resolves the issue above, but is unwieldy, and exposes
all internals of all subparts to each other.
So my question is, what workarounds exist for this limitation, and what are the pros & cons? Two are mentioned in the JSR - use packages for logical grouping (violating encapsulation); place everything in a single package (unwieldy). Are there other pros/cons to these workarounds? Are there other solutions? (I've become vaguely aware of OSGi bundles, but I've found it hard to understand how they work and what the the pros/cons might be (perhaps that's a con). It appears to be very intrusive compared to vanilla packages, to development & deployment.
Note: I'll upvote any good answers, but the the best answer will be one that comprehensively folds in the pros & cons of others (plagiarise!).
Related (but not duplicate!) questions
Anticipating cries of 'Possible duplicate', here are similar questions that I've found on SO; I present them here for reference and also to explain why they don't answer my question.
Java : Expose only a single package in a jar file: asks how to do it, but given that it's not possible in current releases of Java, doesn't discuss workarounds. Has interesting pointers to forthcoming Modularization (Project Jigsaw) in Java 8.
Package and visibility - duplicate question of the above, basically.
Best practice for controlling access to a ".internal" package - question and answers seem to be specific to OSGi or Eclipse plug-ins.
Tools like ProGuard can be used to repackage a JAR, exposing only those classes you specify in the configuration file. (It does this in addition to optimizing, inlining, and obfuscating.) You might be able to set up ProGuard in e.g. a Maven or Ant build, so you write your library exposing methods as public, and then use ProGuard to eliminate them from the generated JAR.
I'll get the ball rolling. Steal this answer and add to it/correct it/elaborate please!
Use multiple packages for multiple logical groupings
Pros: effective logical grouping of related code.
Cons: when internal implementation detail classes in different packages need to use one another, they must be made public - even to the end user - violating encapsulation. (Work around this by using a standard naming convention for packages containing internal implementation details such as .internal or .impl).
Put everything in one package
Pros: effective encapsulation
Cons: unwieldy for development/maintenance of the library if it contains many classes
Use OSGi bundles
Pros: ? (do they fix the problem?)
Cons: appears to be very intrusive at development (for both library user and author) and deployment, compared to just deploying .jar files.
Wait for Jigsaw in Java 8
http://openjdk.java.net/projects/jigsaw/
Pros: fixes the problem for good?
Cons: doesn't exist yet, not specific release date known.
I've never found this to be a problem. The workaround (if you want to call it that) is called good API design.
If you design your library well, then you can almost always do the following:
Put the main public API in one package e.g. "my.package.core" or just "my.package"
Put helper modules in other packages (according to logical groupings), but give each one it's own public API subset (e.g. a factory class like "my.package.foobarimpl.FoobarFactory")
The main public API package uses only the public API of helper modules
Your tests should also run primarily against the public APIs (since this is what you care about in terms of regressions or functionality)
To me the "right level of encapsulation" for a package is therefore to expose enough public API that your package can be used effectively as a dependency. No more and no less. It shouldn't matter whether it is being used by another package in the same library or by an external user. If you design your packages around this principle, you increase the chance of effective re-use.
Making parts of a package "globally accessible" really doesn't do any harm as long as your API is reasonably well designed. Remember that packages aren't object instances and as a result encapsulation doesn't matter nearly as much: making elements of a package public is usually much less harmful than exposing internal implementation details of a class (which I agree should almost always be private/protected).
Consider java.lang.String for example. It has a big public API, but whatever you do with the public API can't interfere with other users of java.lang.String. It's perfectly safe to use as a dependency from multiple places at the same time. On the other hand, all hell would break loose if you allowed users of java.lang.String to directly access the internal character array (which would allow in-place mutation of immutable Strings.... nasty!!).
P.S. Honourable mention goes to OSGi because it is a pretty awesome technology and very useful in many circumstances. However its sweet spot is really around deployment and lifecycle management of modules (stopping / starting / loading etc.). You don't really need it for code organisation IMHO.

UmlGraph vs APIViz for Maven javadoc generation

I'm wondering if there are any clear reasons to choose UmlGraph over APIViz for javadoc UML diagram generation in a Maven2 build. Are there any integration or features that one has over the other, they seem pretty similar?
There is an interesting thread here about UMLGraph vs apiviz (which are mentioned in this question on SO too) and my understanding is the following:
UMLGraph is older but is really nice (dixit Fowler which has more weight than me).
apiviz is a rewrite of UMLGraph but it's not really clear why the rewrote it.
The "big" advantage of apiviz is that the build won't fail if Graphviz isn't installed (this doesn't justify a whole rewrite though in my opinion).
apiviz doesn't generate graphs automatically, you have to add tags versus UMLGraph do it automatically by default (which can be convenient) and the totally automatic results is fine and easy for all (UMLGraph can also model composition relation with custom javadocs tags).
UMLGraph seems to do more things ("it looks like apiviz does nothing more than provide a view of generalizations and interface utilization" or "the class usage shown by UMLGraph actually helps to understand how a class works") but I didn't check myself and this might be not true anymore or outdated.
So, if you project is public, the fact that apiviz gracefully works without Graphviz is nice. If you have lots of classes, having to add tags in javadoc everywhere is a big pain. If you're looking for special features, UMLGraph might offer more. Actually, I think you should experiment both as you obviously have a better knowledge of your needs and constraints for the final choice.
It is not true that apiviz requires annotations for the generation of graphs, as its documentation clearly states:
APIviz automatically discovers the relationship between packages and classes and their stereotype by default. Additionally, you can use the following doclet tags to add more relationships or to make the generated diagram look cleaner.

A good Design-by-Contract library for Java? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 6 years ago.
Improve this question
A few years ago, I did a survey of DbC packages for Java, and I wasn't wholly satisfied with any of them. Unfortunately I didn't keep good notes on my findings, and I assume things have changed. Would anybody care to compare and contrast different DbC packages for Java?
There is a nice overview on
WikiPedia about Design by Contract, at the end there is a section regarding languages with third party support libraries, which includes a nice serie of Java libraries. Most of these Java libraries are based on Java Assertions.
In the case you only need Precondition Checking there is also a lightweight Validate Method Arguments solution, at SourceForge under Java Argument Validation (Plain Java implementation).
Depending on your problem, maybe the OVal framework, for field/property Constraints validation is a good choice. This framework lets you place the Constraints in all kind of different forms (Annotations, POJO, XML). Create customer constraints through POJO or scripting languages (JavaScript, Groovy, BeanShell, OGNL, MVEL). And it also party implements Programming by Contract.
Google has a open source library called contracts for java.
Contracts for Java is our new open source tool. Preconditions,
postconditions, and invariants are added as Java boolean expressions
inside annotations. By default these do nothing, but enabled via a JVM
argument, they’re checked at runtime.
• #Requires, #Ensures, #ThrowEnsures and #Invariant specify contracts as Java boolean expressions
• Contracts are inherited from both interfaces and classes and can be selectively enabled at runtime
contracts for java.
I tested contract4J one time and found it usable but not perfect.
You are creating contracts for for and after method calls and invars over the whole class.
The contract is created as an assertion for the method. The Problem is that the contract itself is written in a string so you don't have IDE support for the contracts or compile time cheching if the contract still works.
A link to the library
It's been a long time since I've looked at these, but found some old links. One was for JASS.
The other one that I had used (and liked) was iContract by Reliable Systems. It had an ant task that you would run as a preprocessor. However, I can't seem to find it with some google searches, it looks like it has vanished. The original site is now a link farm. Check out this link for some possible ways to get to it.
I'd highly recommend you to consider the Java Modeling Language (JML).
There is a Groovy extensions that enables Design by Contract(tm) in Groovy/Java code - GContracts. It uses so-called closure annotations to specify class invariants, pre- and postconditions. Examples can be found on the project's github wiki.
Major advantage: it is only a single jar without external dependencies and it can be resolved via Maven compliant repositories since its been placed in the central Maven repo.
If you want a plain and simple basic support for expressing your contracts, have a look on valid4j (found on Maven Central as org.valid4j:valid4j). It lets you express your contracts using regular hamcrest-matchers in plain code (no annotations, nor comments).
For preconditions and postconditions (basically assertions -> throwing AssertionError):
import static org.valid4j.Assertive.*;
require(inputList, hasSize(greaterThan(0)));
...
ensure(result, lessThan(4.0));
If you are not happy with the default global policy (throwing AssertionError), valid4j provides a customization mechanism that let's you provide your own implementation of org.valid4j.AssertiveProvider.
Links:
http://www.valid4j.org/
https://github.com/helsing/valid4j
I would suggest a combination of a few tools:
Java's assert condition... or it's more advanced Groovy cousin, Guava's Preconditions.checkXXXX(condition...) and Verify.verify(condition...), or a library like AssertJ, if all you need is just to do simple checks in your 'main' or 'test' code
you'll get more features with a tool like OVal; it can check both objects as well as method arguments and results, you can also fire checks manually (eg to show validation errors on UI before a method is called). It can understand existing annotations eg from JPA or javax.validation (like #NotNull, #Pattern, #Column), or you can write inline constraints like #Pre(expr="x >= 0 && x <= y"). If the annotation is #Documented, the checks will be also visible in Javadocs (you don't have to describe them there as well).
OVal uses reflection, which can make performance issues and other problems in some environments like Android; then you should consider tool like Google's Cofoja, which has less functionality, but depends on compile-time Annotation Processing Tool instead of reflection
I think that many DbC libraries were surclassed by the builtin assert keyword, introduced since Java 1.4:
it is a built-in, no other library is required
it works with inheritance
you can activate/deactivate on package basis
easy to refactoring (e.g. no assertions in comments)
I personally think that the DbC libraries available at present have left a lot to be desired, none of the libraries i looked at played well with the Bean Validation API.
The libraries i looked at have been documented here
The Bean Validation API has a lot of over lap with the concepts from DbC. In certain cases Bean Validation API cannot be used like simple POJO's (non CDI managed code). IMO a think wrapper around the Bean Validation API should suffice.
I found that the existing libraries are a little tricky to add into existing web projects given that they are implemented either via AOP or Byte code instrumentation. Probably with the advent of Bean Validation API this kind of complexity to implement DbC is unwarranted.
I have also documented my rant in this post and hope to build a small library which leverages on the Bean Validation API

Plugging in to Java compilers

I have a post-compilation step that manipulates the Java bytecode of generated classes. I'd like to make life as painless as possible for library consumers, so I'm looking at ways I can make this process automatic and (if possible) compiler agnostic.
The Annotation Processing API provides many of the desired features (automatic service discovery; supported by Eclipse). Unfortunately, this is aimed at code generators and doesn't support manipulation of existing artefacts:
The initial inputs to the tool are
considered to be created by the zeroth
round; therefore, attempting to create
a source or class file corresponding
to one of those inputs will result in
a FilerException.
The Decorator pattern recommended by the API is not an option.
I can see how to perform the step with a runtime agent/instrumentation, but this is a worse option than a manual build step as it would require anyone even peripherally touched by the API to configure their JVMs in a non-obvious manner.
Is there a way to plug into or wrap the compiler tool as invoked by javac? Has anyone successfully subverted the annotation processors to manipulate bytecode, no matter what the doc says?
The Groovy compiler is the only bytecode compiler which allows to hook into the compilation process (example: Generate bytecode to support the Singleton pattern)
The Annotation Processing API is not meant to change the code. As you have already found out, all you can do is install a classloader, examine the bytecode at runtime and manipulate it. It's braindead but it works. This follows the general "we're afraid that a developer could try something stupid" theme which you will find throughout Java. There is no way to extend javac. The relevant classes are either private, final or will change with the next version of Java.
Another option is to write annotated Java, for example you write a class "ExampleTpl.java". Then, you use a precompiler which expands the annotations in that file to get "Example.java". In the rest of the code, you use Example and ignore ExampleTpl.
For Eclipse, there is a bug report to automate this step. I'm not aware of any other work in this area.
It can be done.
Take a look at my blog post Roman Numerals, in our Java where an annotation processor is used to rewrite code. Limitation being that it works with Sun's javac only.

Categories