I'm using the jaxb/jaxws libraries to handle Soap messages. When a soap fault occurs, I have to cast it to one of the message types. That is, I do something like this:
if(exceptionObject instanceof Message1Data){
Integer errorCode = ((Message1ExceptionData) exceptionObject).
getExceptionData().getErrorCode();
}
if(exceptionObject instanceof Message2Data){
Integer errorCode = ((Message2ExceptionData) exceptionObject).
getExceptionData().getErrorCode();
}
//...
For a bunch of different types of messages. All of which have the function getErrorCode() but are auto generated so there isn't any kind of class inheritance.
So this turns into a long series of if statements to just get the errorCode out, which always exists. Is there a way to tell the compiler that its OK to call this function on the object, similar how I would cast an object in order to access certain functions. So instead of doing a bunch of if statements I can remove it and do something like
Integer errorCode = exceptionObject.getExceptionData().getErrorCode();
once, instead of the same code for each type of message? Or is there an option in jaxb/jaxws to tell it that each of these classes implement an interface? (Short of writing a custom library that allows this)
JAXB2 Inheritance Plugin allows you to make your classes implement a given interface or extends a certain class.
Customization directly in the schema:
<xs:complexType name="WillBeMadeCloneableType">
<xs:annotation>
<xs:appinfo>
<inheritance:implements>java.lang.Cloneable</inheritance:implements>
</xs:appinfo>
</xs:annotation>
<!-- ... -->
</xs:complexType>
Or in an external binding file:
<jaxb:bindings node="xsd:simpleType[#name='MyType']">
<inheritance:implements>java.lang.Cloneable</inheritance:implements>
</jaxb:bindings>
You can also use generics.
Customizing WSDLs is a bit trickier, but is also possible.
Disclosure: I am the author of the JAXB2 Inheritance plugin which is the part of the JAXB2 Basics package.
Documentation is currently being moved to GitHub. Please check the following links:
Actual documentation on the plugin
Using JAXB2 Basics plugins
Not sure how your objects are setup, hopefully it has a base exception that contains your errorCode, because using instanceOf is very bad way to tell what exception you have. You probably should base what Exception you have base on your errerCode:
interface ExceptionBase extends Exception { public int getErrorCode; }
class Message1ExceptionData implements ExceptionBase {
public int getErrorCode() { return 1; }
}
class Message2ExceptionData implements ExceptionBase { ... return 2; }
switch(exceptionObject.getErrorCode()) {
case 1: Message1ExceptionData exception = (Message1ExceptionData) exceptionObject;
case 2: ...
}
Reflection might work. It depends on the exact structure of the exception classes. Something like that might do the trick:
Method method = exceptionObject.getClass().getMethod("getExceptionData");
ExceptionData exceptionData = (ExceptionData) method.invoke(exceptionObject);
Integer errorCode = exceptionData.getErrorCode();
Related
I have thumbnails saved in my database as a byte array. I can't seem to workout how to return these to the frontend clients via GraphQL.
In a standard REST approach I just send a POJO back with the bytes and I can easily render that out.
However trying to return a byte[] is throwing
Unable to match type definition (ListType{type=NonNullType{type=TypeName{name='Byte'}}}) with java type (class java.lang.Byte): Java class is not a List or generic type information was lost: class java.lang.Byte
The error is descriptive and tells me what's wrong, but I don't know how to solve that.
My thumbnail.graphqls looks like:
type Thumbnail {
id: ID!
resource: [Byte!]
}
And the thumbnail POJO
public class Thumbnail extends BaseEntity {
byte[] resource;
}
I'm using graphql-spring-boot-starter on the Java side to handle things, and I think it supports Byte out the box, so where have I gone wrong?
Very fresh to GraphQL so this could just be an obvious mistake.
Cheers,
You have to serialize it to one of the standard types.
If you want your byte array to look like a string such as "F3269AB2", or like an array of integers such as [1,2,3,4,5] its totally up to you.
You can achieve the serialization by writing a resolver for your entity, like that:
public class ThumbnailResolver extends GraphQLResolver<Thumbnail> {
public String resource(Thumbnail th) { ... }
//or List<Integer> resource(Thumbnail th) { ... }
//or whatever
}
The resolver have always priority over your entity. This means that if a resolver method with the correct name, parameters and return type is found in the resolver class, this will be called instead of the entity method. This way we can "override" entity methods, in order to return an other result, even a different type than the actual entity field. By using resolvers, we could also have access to application scoped services etc that an entity typically does not have.
After writing your resolver, don't forget to update your schema file to:
resource: String
#or resource:[Int]
#or whatever
Your schema should refere to the resolver type since this is what graphQL recieves. The actual entity type will become then irrelevant to graphQL.
As a plan B, you could implement a new Scalar. This would be like inventing a new basic type. This is also not that hard. You can see the already existing scalar types here and do something similar.
You can then name your new type ByteArray or something like that, declare it in your schema:
scalar ByteArray
and then use it.
I would go for the first solution though since it is easier and faster to implement.
There is dsl.DefaultExpander and dsl.DefaultExpanderResolver. Design and javadoc gives an idea I can add my custom expander to the flow. But I didn't found real possibility to do that. Do you see how could I achieve DSL to parsed with my custom expander?
Well, in KnowledgeBuilderImpl (the class used to compile DRL/DSL) I see the following method:
public DefaultExpander getDslExpander() {
DefaultExpander expander = new DefaultExpander();
if (this.dslFiles == null || this.dslFiles.isEmpty()) {
return null;
}
for (DSLMappingFile file : this.dslFiles) {
expander.addDSLMapping(file.getMapping());
}
return expander;
}
As you can see, DefaultExpander is hardcoded in there, so I guess there is no way to specify any other implementation.
Same thing happens in DrlParser.getDefaultResolver() where a DefaultExpanderResolver is always instantiated no matters what.
In my opinion, the only way to go is to pre-generate your DRL (outside Drools) based on your own semantics and then to feed the generated DRL to Drools.
Hope it helps,
Would the following use case be considered as justified for Reflection?
There are bunch of classes generated from XSDs (hundreds currently on project) which represent various Responses.
All of these Responses include common response data structure, rather then extending it.
When event such as timeout happens, i only need to set single String to specific value.
If these classes were extending common response structure i could always set this response code without reflection, but this is not the case.
Therefore i wrote simple utility for my services which uses reflection to get setter method for the String field and invoke it with predefined value.
Only known alternative to me would be to have class specific methods which would duplicate code to handle timeout, with the only difference of returned Response class.
protected T handleTimeout(Class<T> timeoutClass) {
try {
T timeout = timeoutClass.newInstance();
Method setCode = timeoutClass.getDeclaredMethod(SET_RESPONSE_CODE, String.class);
setCode.invoke(timeout, Response.TIMEOUT.getCode());
return timeout;
} catch (InstantiationException | IllegalAccessException | SecurityException | NoSuchMethodException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
throw new RuntimeException("Response classes must have field: \"code\" !");
}
}
Relevant fact:
this setter method should never change as it would require rework of hundreds of interfaces
Could somebody point out if there are some pitfalls i have missed or if there is alternate solution for reflection which would achieve the same result ?
Edit: I simply have no authority to get any changes done on XSDs, so any solution would have to be done locally. There should be no problems with serializing such objects, as they are shared between components.
Firstly there is a standard, normal everyday solution as suggested by #kutschkem, specifically: declare an interface that only contains this one setter method and implement that interface in every class which requires it. This uses standard polymorphism to do exactly what you need.
I understand this requires changing the definition of a lot of classes (but the change is trivial - just add 'implements MytimeoutThing' to every class) - even for 1000's of classes this seems a fairly easy fix for me.
I think that there are real problems with reflection:
You are creating a secret interface to all your classes that must be supported but there is no contract for this interface - when a new developer wants to add a new class he has to magically know about the name and signature for this method - if he gets it wrong the code fails at run-time as the compiler doesn't know about this contract. (So something as simple as misspelling the setters name isn;t picked up by the compiler)
It's ugly, hidden and not clearly part of any particular part of the software. A dev maintaining ANY of these classes will find this function (the setter) notice that it is never being called and just delete it - after all no code in the rest of the project refers to that setter so it obviously isn't needed.
A whole lot of static analysis tools won;t work - for example in most IDE's you can establish all the places that specific function is called from and all the places that a specific function calls - obviously this kind of functionality is not available if you use reflection. In a project with hundreds of near identical classes I would hate to loose this facility.
The actual problem you are facing is that you have a lot of classes that should share a common abstraction between them (inheriting the same class or implementing the same interface), but they don't. Trying to keep it that way and designing around would basically be taking care of the symptoms instead of the cause and will likely cause more problems in the future.
I suggest to solve the root cause instead by making all the generated classes have a common interface / superclass. You do not have to do this by hand - as they are all generated it should be possible to change them automatically without much struggle.
I'd try an alternate solution for generating your classes from the xml schema, in preference over reflection.
You can supply xjc with a custom binding like this:
<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns="http://java.sun.com/xml/ns/jaxb"
xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd" version="2.1">
<globalBindings>
<xjc:superClass name="XmlSuperClass" />
</globalBindings>
</bindings>
and implement you XmlSuperClass like this:
#XmlTransient // to prevent that the shadowed responseCode be marshalled
public class XmlSuperClass {
private String responseCode; // this will be shadowed
public String getResponseCode() { // this will be overridden
return responseCode;
}
public void setResponseCode(String value) { //overridden too
this.responseCode = value;
}
}
Invoking xjc like this:
xjc -extension -b <yourbinding.xjb> -cp <XmlSuperClass> <xmlschemas.xsd...>
will generate bound classes like:
#XmlRootElement(name = "whatever")
public class Whatever extends XmlSuperClass {
#XmlElement(required = true)
protected String responseCode; // shadowing
public void setResponseCode(String...) //overriding
}
To become objective again:
There is no mention of the object instantiation.
If you would have postulated a constructor with a String code parameter:
T timeout = timeoutClass.getConstructor(String.class)
.newInstance(Response.TIMEOUT.getCode());
Would the save critics arise? To a lower extent, as parametrized constructors are even more indeterminate. Let's await the voting here.
Interface is better looking though.
interface CodeSetter {
void setCode(String code);
}
protected <T extends CodeSetter> handleTimeout(Class<T> timeoutClass) {
try {
T timeout = timeoutClass.newInstance();
timeout.setCode(Response.TIMEOUT.getCode());
return timeout;
Okay, so let's suppose you've got this generated code:
public class Response1 {
public void setResponseCode(int code) {...}
}
public class Response2 {
public void setResponseCode(int code) {...}
}
What you need to do then is write an interface:
public interface ResponseCodeAware { //sorry for the poor name
public void setResponseCode(int code);
}
Then you need to write a script that goes through all the generated code files and simply adds implements ResponseCodeAware after every class definition. (That's assuming that there are no interfaces implemented already, in that case you have to play around a bit with the string processing.)
So your generated and post-processed classes will now look like this:
public class Response1 implements ResponseCodeAware {
public void setResponseCode(int code) {...}
}
public class Response2 implements ResponseCodeAware {
public void setResponseCode(int code) {...}
}
Note that nothing else changed, so code that doesn't know about your interface (including serialization) should work exactly the same.
And finally we can rewrite your method:
protected T handleTimeout(Class<T extends ResponseCodeAware> timeoutClass) {
try {
T timeout = timeoutClass.newInstance();
timeout.setResponseCode( Response.TIMEOUT.getCode() );
return timeout;
} catch (InstantiationException | IllegalAccessException | SecurityException | NoSuchMethodException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
throw new RuntimeException("Response class couldn't be instantiated.");
}
}
As you can see, unfortunately we still have to use reflection to create our object, and unless we also create some kind of factory, that will stay that way. But code generation can help you here too, you can build up a factory class in parallel to marking the classes with the interface.
How can I change what a method is doing in Java ?
I mean, I am trying to use annotations to make the following code
#Anno1(Argument = "Option1")
public class TestClass
{
#Anno2
public void test()
{
}
}
Into
public class TestClass
{
private static StaticReference z;
public void test()
{
z.invokeToAll();
}
}
This is a very simplified example of what I am trying to do. Anno1 will have many possible combinations, but this is not my problem so far. My problem is how to add code to method test()
I am looking for a more generic solution if possible. Eg. A way to add every kind of code in the method (not just a way to .invokeToAll())
So far I am using import javax.annotation.processing.*; and I have the following code, but I don't know how to go on from there
private void processMethodAnnotations(RoundEnvironment env)
{
for (Element e : env.getElementsAnnotatedWith(Anno2.class))
{
//If it is a valid annotation over a method
if (e.getKind() == ElementKind.METHOD)
{
//What to do here :S
}else
{
processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING,"Not a method!", e);
}
}
}
I have found something about Java Reflection but I have not found any source to help me with what I am doing.
Obviously I extends AbstractProcessor in my code
I have found this tutorial (http://www.zdnetasia.com/writing-and-processing-custom-annotations-part-3-39362483.htm) But this concerns creating a new class, not just changing a method. and the javax.lang.model.elements do not provide any way of editing that element (which in my case represents a Method).
I hope my question is clear and inline with the rules. If not please comment and I will clarify. Thanks.
Annotation processing is the wrong way to go for you, from Wikipedia:
When Java source code is compiled,
annotations can be processed by
compiler plug-ins called annotation
processors. Processors can produce
informational messages or create
additional Java source files or
resources, which in turn may be
compiled and processed, but annotation
processors cannot modify the annotated
code itself.
People suggested to you the right way - AOP. Specifically, you can use AspectJ. "Quick result" way is (if you use Eclipse):
Install AJDT (AspectJ Development Tools)
Create an AspectJ project and add there your classes and annotations
Create Aspect:
public aspect Processor {
private StaticReference z;
pointcut generic()
// intercept execution of method named test, annotated with #Anno1
// from any class type, annotated with #Anno2
: execution(#Anno2 * (#Anno1 *).test())
// method takes no arguments
&& args ();
// here you have written what you want the method to actually do
void around () : generic() {
z.invokeToAll();
}
}
now you can execute a test and you will see that it works ;) AJDT compiles code for you automatically, so do not need any manual work to do, hope that's what you called "magic" ;)
UPDATE:
if your code in the test() method depends on the Anno1 annotation value, then inside aspect you can get class annotation for which it is executed this way:
void around () : generic() {
Annotation[] classAnnotations = thisJoinPoint.getThis().getClass().getAnnotations();
String ArgumentValue = null;
for ( Annotation annotation : classAnnotations ) {
if ( annotation instanceof Anno1 ) {
ArgumentValue = ((Anno1) annotation).Argument();
break;
}
}
if ( ArgumentValue != null && ArgumentValue.equals("Option1")) {
z.invokeToAll();
}
}
where thisJoinPoint is a special reference variable.
UPDATE2:
if you want to add System.out.println( this ) in your aspect, you need to write there System.out.println( thisJoinPoint.getThis() ), just tested and it works. thisJoinPoint.getThis() returns you "this" but not exactly; in fact this is Object variable and if you want to get any propery you need either to cast or to use reflection. And thisJoinPoint.getThis() does not provide access to private properties.
Well, now seems that your question is answered, but if I missed anything, or you get additional question/problems with this way - feel free to ask ;)
It's perfectly possible to do what you ask, although there is a caveat: relying on private compiler APIs. Sounds scary, but it isn't really (compiler implementations tend to be stable).
There's a paper that explains the procedure: The Hacker's Guide to Javac.
Notably, this is used by Project Lombok to provide automatic getter/setter generation (amongst other things). The following article explains how it does it, basically re-iterating what is said the aforementioned paper.
Well, you might see if the following boilerplate code will be useful:
public void magic(Object bean, String[] args) throws Exception {
for (Method method : bean.getClass().getDeclaredMethods()) {
if (method.isAnnotationPresent(Anno2.class)) {
// Invoke the original method
method.invoke(bean, args);
// Invoke your 'z' method
StaticReference.invokeAll();
}
}
}
As an alternative your might employ aspect oriented programming, for instance you have the AspectJ project.
I'm not sure at all if it is even possible to change the source or byte code via annotations. From what your describing it looks as if aspect oriented programming could provide a solution to your problem.
Your annotations are pretty similiar to the pointcut concept (they mark a location where code needs to be inserted) and the inserted code is close the advice concept.
Another approach would be parsing the java source file into an abstract syntax tree, modify this AST and serialize to a java compiler input.
If your class extends a suitable interface, you could wrap it in a DynamicProxy, which delegates all calls to the original methods, except the call to test.
Is there any way to require that a class have a default (no parameter) constructor, aside from using a reflection check like the following?
(the following would work, but it's hacky and reflection is slow)
boolean valid = false;
for(Constructor<?> c : TParse.class.getConstructors())
{
if(c.getParameterTypes().length == 0) {
valid = true;
break;
}
}
if(!valid)
throw new MissingDefaultConstructorException(...);
You can build an Annotation processor for that. Annotation Processors are compiler plugins that get run at compile time. Their errors show up as compiler errors, and may even halt the build.
Here is a sample code (I didn't run it though):
#SupportedAnnotationTypes("*") // needed to run on all classes being compiled
#SupportedSourceVersion(SourceVersion.RELEASE_6)
public class DefaultConstructor extends AbstractProcessor {
#Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
for (TypeElement type : ElementFilter.typesIn(roundEnv.getRootElements())) {
if (requiresDefaultConstructor(type))
checkForDefaultConstructor(type);
}
return false;
}
private void checkForDefaultConstructor(TypeElement type) {
for (ExecutableElement cons :
ElementFilter.constructorsIn(type.getEnclosedElements())) {
if (cons.getParameters().isEmpty())
return;
}
// Couldn't find any default constructor here
processingEnv.getMessager().printMessage(
Diagnostic.Kind.ERROR, "type is missing a default constructor",
type);
}
private boolean requiresDefaultConstructor(TypeElement type) {
// sample: require any JPA Entity to have a default constructor
return type.getAnnotation(Entity.class)) != null
|| type.getQualifiedName().toString().contains("POJO");
}
}
The annotation processor becomes even easier if you introduce an annotation (e.g. RequiresDefaultAnnotation).
Declaring the requirement of having a default qualifier
::I am also assuming that the OP asking for a mechanism that prevents accidental errors for developers, especially written by someone else.::
There has to be a mechanism to declare which classes require a default processor. Hopefully, you already have a criteria for that, whether it is a pattern in the name, pattern in the qualifier, a possible annotation, and/or a base type. In the sample I provided above, you can specify the criteria in the method requiresDefaultConstructor(). Here is a sample of how it can be done:
Based on a name pattern. TypeElement provide access to the fully qualified name and package name.
return type.getQualifiedName().toString().contains("POJO");
Based on an annotation present on the type declaration. For example, all Java Bean Entity classes should have a non-default constructors
return type.getAnnotation(Entity.class) != null;
Based on a abstract class or interface.
TypeElement basetype = processingEnv.getElements().getTypeElement("com.notnoop.mybase");
return processingEnv.getTypes().isSubtype(type.asType(), basetype.asType());
[Recommended Approach]: If you are using the basetype interface, I recommend mixing the annotation approach with the base type interface. You can declare an annotation, e.g. MyPlain, along with the meta annotation: #Inherited. Then you can annotate the base type with that annotation, then all subclasses would inherit the annotation as well. Then your method would just be
return type.getAnnotation(MyPlain.class) != null;
This is better because it's a bit more configurable, if the pattern is indeed based on type hierarchy, and you own the root class.
As mentioned earlier, just because it is called "annotation processing", it does mean that you have to use annotations! Which approach in the list you want to follow depends on your context. Basically, the point is that whatever logic you would want to configure in your deployment enforcement tools, that logic goes in requiresDefaultConstructor.
Classes the processor will run on
Annotation Processors invocation on any given class depends on SupportedAnnotationTypes. If the SupportedAnnotationTypes meta-annotation specifies a concrete annotation, then the processor will only run on those classes that contain such annotation.
If SupportedAnnotationTypes is "*" though, then the processor will be invoked on all classes, annotated or not! Check out the [Javadoc](http://java.sun.com/javase/6/docs/api/javax/annotation/processing/Processor.html#getSupportedAnnotationTypes()), which states:
Finally, "*" by itself represents the
set of all annotation types, including
the empty set. Note that a processor
should not claim "*" unless it is
actually processing all files;
claiming unnecessary annotations may
cause a performance slowdown in some
environments.
Please note how false is returned to ensure that the processor doesn't claim all annotations.
No. The above check can be easier rewritten as:
try {
MyClass.newInstance();
} catch (InstantiationException E) {
// no constructor
} catch (IllegalAccessException E) {
// constructor exists but is not accessible
?
You can employ PMD and Macker in order to guarantee architectural rules.
In partilar, Macker provokes compilation errors, breaking your build process when validations fail.
Macker extends some concepts made popular by PMD regarding validations of source code. A good example is when you'd like to guarantee that all classes from a package implements a certain interface.
So, if you are very paranoid (like me!) about verifying all possible architectural rules, Macker is really useful.
http://innig.net/macker/
Note: The website is not great. Colors will hurt your eyes... but the tools is very useful anyway.
Richard Gomes
http://www.jquantlib.org/