I was wondering if I can easily annotate Acceleo templates and then get these annotations when working with TraceabilityModel.
Acceleo is now using an annotation to determine entry points for generation:
[comment #main]
So I am asking, if I can use this mechanism to annotate my templates for other purposes, for example:
[comment #org.project.SimpleStatement]
[template public generateSimpleStatement(...)]
...
[/template]
Then, I could be able to get the annotation programmatically when working with traceability model (probably using the org.eclipse.acceleo.traceability.ModuleElement interface).
Acceleo's traceability does not support either annotations or comments : we only record traceability information for the actually generated text bits, not for any of the "extra" information (comments of the module, main annotation, metamodels ...).
That being answered, and though not possible through the means of an annotation, maybe your use case would be worth an enhancement request? Can you describe what you were expecting to achieve through this? (preferrably through the Eclipse M2T forum since stack overflow does not seem to be appropriate for such discussions ;)).
(Note : I am an active developper on Acceleo)
Related
I have recently started to look at OpenApi code generator and I have a few questions that I couldn't find an answer to with the usual resources (google and documentation mostly).
What I want to generate via the components.yaml and the code generator:
An interface with a couple of methods (lets just say getters and setters for example)
Have several model like classes that implement this interface
After several hours of trying to accomplish this I have the following questions:
For item 1: Is this even possible with the code generator? If so can I do it without custom mustache templates and how?
Still for item 1: If mustache template is the only way to go, how can I make sure the object that I defined in components.yaml can point to that specific custom template.
For item 2: How do I make sure that the generated code for the model-like class implements the previously generated interface? Is there a specific key for components.yaml that allows me to do this?
Any help would be greatly appreciated!
Is there something special to the #Deprecated annotation that I cannot reproduce?
I need to create an annotation similar to #Deprecated to produce warnings in Eclipse and also at build time. When I mark a method as #Deprecated I get nice warnings. For example, if I have an old method (that I may still keep for compatibility reasons):
#Deprecated
public List<Account> getClientAccounts(final int clientId) {
// Implement search...
}
Then, if I try to use it in Eclipse I can see it strikethrough, and a yellow icon in the left bar:
Also when building I can see the:
[WARNING] app1/src/test/java/com/app1/MyApp.java: app1/src/test/java/com/app1/MyApp.java uses or overrides a deprecated API.
Now, depending on external factors I cannot control (e.g. absence of database indexes) some methods are not optimal, and I would like to clearly mark them as such... with my brand new #NonOptimal annotation. I need to add visibility to the problem. So far I have:
#Retention(RUNTIME)
#Target(METHOD)
// What else here?
public #interface NonOptimal {
}
How can I create this annotation?
I wish I could extend Deprecated, but no can do.
After reading about this quite a bit I ended up with an ugly workaround. It works, though I don't like it.
I decided to mark the bad methods with both the #Deprecated and #NonOptimal annotations. It's conceptually wrong (the methods are not actually deprecated) but it works well out of the box. No need to develop an overkill Eclipse plugin:
The #Deprecated annnotation bugs developers all around the place (in Eclipse and when building), and that's a good thing.
The #NonOptimal annotation provides details on why this is a bad method to use.
Ugly but works. As of now Eclipse does not provide any better option.
Note: to make things worse, the NonOptimal annotation does not work well in Maven when using toolchains: warnings go silent, disappear, nada... Therefore, AnnotationProcessors are kind of useless in the end.
#TheImpaler This is actually not a true answer for your problem, but some time ago I came across the Google Annotations Library (a.k.a. gag) while using Zalando's Problem API.
This library provides a great number of custom annotations that, in some cases, can be used to instrument your actual code by using a ASM and a custom java agent.
Maybe it can give you some ideas regarding your actual issue.
The project is no longer maintained but there is a fork in Github.
I'm new in Play 2 Framework v. 2.1.1 with Java and I'm looking for the best way to do the following without duplicating code.
To simplify, I have a Play 2 backoffice that uses an external API. I don't manage this API, but I call REST Services to perform operations over the api.
This API's objects are exactly the same as Play 2 Model Objects. But I don't want to duplicate the api objects to add Play validations and other annotations.
Is there any way to add this type of behavior using configuration files? I'm thinking about something like Hibernate hbm's for example.
For example:
Object in the unmanaged api: (I omit getters and setters for simplicity)
public class Entity{
public String field1;
public String field2;
}
Object that I want to avoid: (I omit getters and setters for simplicity)
public class Entity1{
#Required
#NonEmpty
#MinLength(3)
public String field1;
#Required
#NonEmpty
public String field2;
}
Config example: (I need something like this)
<class name="Entity1">
<property name="field1" >
<required/>
<nonEmpty/>
<minLength value="3"/>
</property>
<property name="field2" >
<required/>
<nonEmpty/>
</property>
</class>
Using annotations seems better than using xmls or any other configuration file, so I don't necessarily want to use configuration files, I'm open to any suggestions to solve this problem.
Thanks
I can't see how duplicating the API model in a non typesafe descriptor like XML is better than using a typesafe language. Moreover, I would not want to couple my model and application to a model from the API under my control.
I think it is far better to duplicate the model in Java/Scala and use a simple bean copier like dozer to move between the two.
One problem is ebean as the persistence provider - in ebean there is no way to externalize the bean persistence configuration as it is possible in hibernate (except for sql queries). Is a switch of the persistence provider possible? Play seems to allow that.
Since you wrote that you are unable to modify the entities source code and you don't want to copy the source, the only other possibility I see is bytecode enhancement.
What you need is a library that would allow you to externalize annotations in a xml file. This library would use the instrumentation api, read the xml file at jvm statup and modify the bytecode of each listed class in order to add annotations to the class and fields at runtime.
There are two problems with this approach:
There is no such library (at least I couldn't find it)
Play and EBean use their own agent / classloader in order to allow hot deployment and persistence
The first problem is the easy and fun part, see for example https://today.java.net/pub/a/today/2008/04/24/add-logging-at-class-load-time-with-instrumentation.html. With javaassist it is easy to add annotations to classes and fields. The mapping from xml to annotations is straight foreward. And it would be a nice open source project.
The second problem looks much harder, because you must install your annotation agent so that it executes before play and ebean start to parse the annotations.
It is not clear to me why can't add annotations in your own app, but if you have such constraints why don't you just extend the class, override the variables, add the annotations, and use that as an EBean model?
Play has dynamic forms, which let you validate against a map of key,value pairs. If validation is what you want you could copy an entity's data to a map and validate that.
Simple answer: There is not always code duplication also if the code lines are the same.
Robert C. Martin shows this in one of his talks: the single responsible principle. There are two ways to break this principle: On the one hand two responsibilities in one code fragment on the other hand one responsibility handled independently bei two code fragments.
Code duplication is a matter responsibility and semantics not of code lines that are the same (which may be at most an indicator for having code duplication).
In your case the responsibilities are clearly separated: You have an external API and your code. So there is no code duplication.
I have developed a library that generates at runtime especialization classes of an abstract class given certain annotations in the abstract class.
So my library is used a bit like:
X x = newInstance(X.class) //X is an abstract class
This library uses Javassist for the generation of a subclass at runtime that will be instantiated by the newInstance method.
As far as I understand Hibernate also makes use of Javassist to instrument at runtime entity classes (please someone correct me if that is not the case).
My question is if it is possible to make the two frameworks work together ?. I mean, can I tell Hibernate that every time that it needs an instance of an entity class (an abstract class) it should use a specific factory method from my library ?.
I do not know if Hibernate works behind the courtains by also generating subclasses at runtime of entity classes (assuming Hibernate also needs to instrument them). If that is the case the solution of passing to Hibernate a factory for certain classes will not work.
In that case, does Hibernate have any kind of support for working with abstract entity classes ?. I mean, it should be possible to work with abstract (or interface?) entity classes and somehow tell to Hibernate which is the right concrete class it should instrument when required to work with one of these abstract entity classes.
But an additional complication is that the concrete class especializing the abstract entity class does not exist at compile-time.
Before heading to the your asnwer:
Yes you are correct, Hibernate currently uses Javassist (in the past it used GCLib, but it was deprecated) to instrument classes at runtime.
Hibernate does creates subclasses at runtime that work has proxy for you persistent entities.
Short answer
Sadly, I don't think you will be able to configure Hibernate to use your own factory. For details I invite you to read the long answer part.
Long answer
For what I know, currently, Hibernate 4.x only supports Javassist as its bytecode manipulation provider. Although, it used to allow you to switch between GClib and Javassist in the 3.x versions. Back in those versions you could modify the factory to be used by configuring an hibernate global setting called hibernate.bytecode.provider.
This setting no longer shows up in the Hibernate 4.1 documentation but you still can find a bit about it in the documentation for Hibernate 3.2 under the optional configuration properties.
Being myself a developer I know that sometimes we are some tricky fellows and just because something is out of the docs doesn't mean necessarily it's out of the code :-) So, I though maybe if the setting still exists we could try to exploit it in order to do what you want (in a non-supported way, though).
For the sake of curiosity since I had Hibernate 4.0.1 code (notice that is not the latest, though) in my machine I did some digging... And suprise, suprise the property still existed! After tracking for used references (thank you Eclipse) I ended up in the class org.hibernate.cfg.Environment (code for version 4.2.0.CR2) where I found the following code (code was the same both in my version and 4.2.0CR2):
public static BytecodeProvider buildBytecodeProvider(Properties properties) {
String provider = ConfigurationHelper.getString( BYTECODE_PROVIDER, properties, "javassist" );
LOG.bytecodeProvider( provider );
return buildBytecodeProvider( provider );
}
private static BytecodeProvider buildBytecodeProvider(String providerName) {
if ( "javassist".equals( providerName ) ) {
return new org.hibernate.bytecode.internal.javassist.BytecodeProviderImpl();
}
LOG.unknownBytecodeProvider( providerName );
return new org.hibernate.bytecode.internal.javassist.BytecodeProviderImpl();
}
So as far I can tell it's Javassist implementation for your proxy factory and there won't be a standard way to change it.
The madman sidenote
What I'm about to say is pure madness and it should not be taken into account for production code but only in a would it actually work/academic/lets bend things scenario.
<Hammer Hacking>
You could try extend your own framework to instrument the classes in order not only to add the bytecode for your needs but also the bytecode that hibernate needs - which I would say would be something like merging your manipulations with org.hibernate.bytecode.internal.javassist.BytecodeProviderImpl manipulations.
You could then rename your extension class to BytecodeProviderImpl put it in the same package org.hibernate.bytecode.internal.javassist and finally put it somewhere in the classpath where the classloader would find it before the one in the jar (or maybe using a custom class loader)
Then you would just enjoy listening to Hibernate, your framework and probably the entire JVM scream in panic not knowing what to do, or maybe it could work...
</Hammer Hacking>
Anyway, if you have the time and will to try it, let me know if it worked out.
UPDATE
After talking a bit in the comments section I had this idea to use a custom EntityPersister. Since I wasn't very sure about this I googled a bit to see if I could find something that could tell me that what I was thinking would work or not.
Even better than finding out if my gut feeling was right or not, I found a question in Stackoverflow that seems pretty similar to yours. Sadly, there's no accepted answer there.
But the first answer to that question, gives a link to something similar to what I was thinking. Quoting Pascal Thivent:
a custom EntityPersister implementation (that you can register for a particular entity during Hibernate initialization using a custom Configuration)
It's true that the example is for Hibernate in Grails but it's pretty much the same in plain Java:
public void registerCustomEntityPersister(Configuration configuration) {
final Iterator<PersistentClass> classesIterator = configuration.getClassMappings();
while (classesIterator.hasNext()) {
final PersistentClass persistentClass = classesIterator.next();
if (checkIfIsOneTheClassesThatMatters(persistentClass)) {
persistentClass.etEntityPersisterClass(CustomEntityPersister.class);
}
}
Even though this seems doable, it looks like way too much work because implementing the EntityPersister doesn't look that trivial... way too many things. You could try to extend the default one Hibernate uses (which I really don't know which one is) and try to override the getProxy() method in order to return one of your instrumented classes.
Sorry if it's still not a spot on answer, but sadly I'm no Hibernate expert I just use it usually out of the box, I actually landed on your question due to the javassist tag and found it quite interesting.
I hope that at least I gave you information that can help you out.
This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
How and where are Annotations used in Java?
Java beans, annotations: What do they do? How do they help me?
Over and over, I read about Java 5's annotations being an 'advanced feature' of the language. Until recently, I haven't much used annotations (other than the usual #Override, &c), but work on a number of webservice-related projects has forced my hand. Since I learned Java pre-5, I never really took the time to sit down and grok the annotation system.
My question- do you guys actually use annotations? How helpful are they to you, day-to-day? How many StackOverflow-ers have had to write a custom annotation?
Perhaps the most useful and used case of Java Annotations is to use POJO + Annotation instead of xml configuration files
I use it a lot since (as you already stated) if you use a web framework (like spring or seam) they usually have plenty of annotations to help you.
I have recently wrote some annotations to build a custom statemachine, validations purpose and annotations of annotations (using the metadata aspect of it). And IMO they help a lot making the code cleaner, easier to understand and manage.
Current project (200KLOC), annotations I use all the time are:
#NotNull / #Nullabe
#Override
#Test
#Ignore
#ThreadSafe
#Immutable
But I haven't written yet my own annotation... Yet!
I have used annotations for:
Hibernate, so I don't need to keep those huge XML files;
XML Serialization, so I describe how the object should be rendered in the object itself;
Warning removal for warnings that I don't want to disable (and for which the particular case cannot be properly solved).
I have created annotations for:
Describe the state required in order for my method to be executed (for example, that a user must be logged in);
Mark my method as executable from a specific platform with additional properties for that platform;
And probably some other similar operations.
The annotations that I have created are read with Reflection when I need to get more information about the object I am working with. It works and it works great.
Annotations are just for frameworks and they do work great in hibernate/jpa. until you write a framework that needs some extra information from passed to it objects you wont write your own annotations.
however there is new and cool junit feature that let you write your own annotations in tests - http://blog.mycila.com/2009/11/writing-your-own-junit-extensions-using.html
I use annotations daily and they are wonderful. I use them with jsf and jpa and find them much easier to manage and work with than the alternative XML configurations.
I use annotations for describing in my state synchronisation system what classes are specialisations of the annotated classes, and the environment in which they should be used (when an object is created, it will work out for its entity lists which are the best entity classes to create for the nodes on the network; i.e., a Player entity for a server node is instead a ServerPlayer entity). Additionally, the attributes inside the classes are described and how they should be synchronised across machines.
We just used annotations to create a simple way to validate our POJO's:
#NotEmpty
#Pattern(regex = "I")
private String value;
Then we run this through the Hibernate validator which will do all our validation for us:
import org.hibernate.validator.ClassValidator;
import org.hibernate.validator.InvalidValue;
public void validate(T validateMe) {
ClassValidator<T> validator = new ClassValidator<T>((Class<T>) validateMe.getClass());
InvalidValue[] errors = validator.getInvalidValues(validateMe);
}
Works great. Nice clean code.
We use custom annotations as a part of our integration testing system:
#Artifact: Associates an integration test with an issue ID. Trace matrices are then automatically generated for our testing and regulatory departments.
#Exclude: Ignores an integration test based on the browser platform / version. Keeps the IE 6 bugs from clogging up our nightly test runs :)
#SeleniumSession: Defines test specific selenium settings for each integration test.
They are a very powerful tool, but you gotta use them carefully. Just have a look at those early .NET Enterprise class files to see what a nightmare mandatory annotations can be :)
We have a report builder as part of our webapp. A user can add a large number of widgets that are all small variations on the same set of themes (graphs, tables, etc).
The UI builds itself based on custom annotations in the widget classes. (e.g. an annotation might contain default value and valid values that would render as a dropdown. Or a flag indicating if the field is mandatory).
It has turned out be be a good way to allow devs to crank out widgets without having to touch the UI.