All my life I worked with C++, but recently decided to play a bit with Java. I have started with learning Jackson serialier/desirialer library. The basic example looks like that
ObjectMapper objectMapper = new ObjectMapper();
Car car = new Car("yellow", "renault");
objectMapper.writeValue(new File("target/car.json"), car);
It looks pretty easy and no problems should arise here. My IDE is IntelliJ, so before running the code I used Maven to get next libraries
com.fasterxml.jackson.core:jackson-annotations:2.9.4
com.fasterxml.jackson.core:jackson-core:2.9.4
com.fasterxml.jackson.core:jackson-databind:2.9.4
Taking into account that class Car is implemented somewhere above it should now work. However when I try to build the code I get an error that compiler can't resolve the symbol writeValue(). Autocomplition faces the same problem. My first assumption is that not all external libraries are correclty resolved, but when I open the source code for ObjectMapper in IDE I clearly see method writeValue(). Even more if I try to call this method just after the creating object with operator new autocomplition is able to recognize it. If I remove the line with
writeValue() call code successfully compiles.
From C++ prospective it looks like madness, so please suggest why it happens and how it can be resolved?
Related
I am trying to create a plugin to generate some java code and write back to the main source module. I was able to create a some simple pojo class using JavaPoet and write to the src/main/java.
To make this useful, it should read the code from src/maim/java folder and analyze the classes using reflection. Look for some annotation then generate some codes. Do I use the SourceTask for this case. Looked like I can only access the classes by the files. Is that possible to read the java classes as the class and using reflection analyze the class?
Since you specified what you want to do:
You'll need to implement an annotation processor. This has absolutely nothing to do with gradle, and a gradle plugin is actually the wrong way to go about this. Please look into Java Annotation Processor and come back with more questions if any come up.
With JavaForger you can read input classes and generate sourcecode based on that. It also provides an API to insert it into existing classes or create new classes based on the input file. In contrast to JavaPoet, JavaForger has a clear separation between code to be generated and settings on where and how to insert it. An example of a template for a pojo can look like this:
public class ${class.name}Data {
<#list fields as field>
private ${field.type} ${field.name};
</#list>
<#list fields as field>
public ${field.type} ${field.getter}() {
return ${field.name};
}
public void ${field.setter}(${field.type} ${field.name}) {
this.${field.name} = ${field.name};
}
</#list>
}
The example below uses a template called "myTemplate.javat" and adds some extra settings like creating the file if it does not exist and changing the path where the file will be created from */path/* to */pathToDto/*. The the path to the input class is given to read the class name and fields and more.
JavaForgerConfiguration config = JavaForgerConfiguration.builder()
.withTemplate("myTemplate.javat")
.withCreateFileIfNotExists(true)
.withMergeClassProvider(ClassProvider.fromInputClass(s -> s.replace("path", "pathToPojo")))
.build();
JavaForger.execute(config, "MyProject/path/inputFile.java");
If you are looking for a framework that allows changing the code more programatticaly you can also look at JavaParser. With this framework you can construct an abstract syntax tree from a java class and make changes to it.
Hello dear Stack Overflow!!! :)
I have a bit of a problem. I am attempting to consume a Hateoas-based application in a project and I'm having issues with Hateoas and it generating a faulty JSON-request for a test. I will provide some code examples!
Basically, I use a JSONconverter that tries to convert my request body(post) to JSON but it throws an error with what I actually get. Some information and code:
Here is my ObjectMapper that I am using:
ObjectMapper objectMapper = (ObjectMapper) bean;
objectMapper.registerModules(new Jackson2HalModule());
Here is my converter config where I plug the objectmapper and the supported media types:
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setSupportedMediaTypes(Arrays.asList(MediaTypes.HAL_JSON, MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_JSON_UTF8));
converter.setObjectMapper(objectMapper);
Here is my RestTemplate where I plug the Jackson 2 Http Converter I just made:
#Bean
public RestTemplate uttagRestTemplate(RestTemplateBuilder builder) {
return builder.messageConverters(mappingJackson2HttpMessageConverter, new StringHttpMessageConverter(Charset.forName("UTF-8")))
Here is the test I run with the output:
mockServer.expect(requestTo(url + "/person/" + id + "/links")).andExpect(header("Content-type", MediaType.APPLICATION_JSON_UTF8.toString()))
.andExpect(header("accept", MediaType.APPLICATION_JSON_UTF8.toString()))
.andExpect(content().string(jsonConverter.toJson(Arrays.asList(link)))).andExpect(method(HttpMethod.POST)).andRespond(withSuccess());
Finally, here is my test output(don't mind the data, it's just test data):
Expected :[{"id":2112,"rel":"EZyb","href":"dspK0XickvvcMw0","type":"RaAmwWkZHlagrcQ","length":992539719,"title":"OuaRoPRClRpvprg"}]
Actual :"[{\"id\":2112,\"rel\":\"EZyb\",\"href\":\"dspK0XickvvcMw0\",\"type\":\"RaAmwWkZHlagrcQ\",\"length\":992539719,\"title\":\"OuaRoPRClRpvprg\"}]"
It seems to do something really weird with the "actual" json-generated body. I'd like to have it match my expected, but no luck.
I've tried solving this, and if I remove the MediaType.HAL_JSON from my MappingJacksonConverter somehow it works in my tests, but then I can't consume the hateoas client. I need the media type there for it to work.
I've also tried writing my expected JSON with my MappingJackson writer, but it produces the exact same expected output.
Does anybody know what's going on here and can help me with this? Do you know how I may generate correct JSON-body to get the assert to work? Frankly it's doing my head in - and choosing between functioning tests without the media type and being able to consume the hateoas application with it obviously isn't an option for me. :(
Cheers for reading if you made it this far! :) Any pointers are welcome.
I figured out what it was. With the new config, it seems that the application automatically converts to json and I didn't need to use my own jsonConverter anymore. So what was going on as basically a toJson conversion on an already jsonified object.
After removing my own jsonconverter implementation, it now functions correctly.
I am having to make use of some existing code. I cannot contact the previous developer. Part of it is a REST application. I can see how it works, but there is a lot of stuff that looks like code duplication. Or there is a tool of some kind which is taking some of the sources and creating articfacts and other sources from that, or it is creating templates, in which code was added. It looks a bit like Jersey but I have not used this in work, so I am not sure. I tried searching for the annotations, but that is not helpful. I may be missing the build files. It was in an eclipse project and I do not seem to have the .project directory.
This project has a lot of partial implementations that got set aside. I am having problems distringushing those from code that should work.
Looking for just "UserEmail", I see:
src/com/gs/dao/user/UserEmailDao.java
src/com/gs/dao/user/UserEmailDaoImpl.java
src/com/gs/service/UserEmailService.java
src/com/gs/service/UserEmailServiceImpl.java
This is not just 4 times the necessary code. Something is driving this structure. But what is it? Any suggestions?
I am seeing code like:
#ApiController("1.0")
public class UserEndpoint extends BaseEndpoint {
Logger logger = Logger.getLogger(UserEndpoint.class);
#Autowired
public UserService userService;
#Autowired
public UserContactService userContactService;
....
The directory structure looks like this:
src/com/gs/cache
src/com/gs/cache/local
src/com/gs/cache/mem
src/com/gs/servlet
src/com/gs/constants
src/com/gs/common
src/com/gs/dao
src/com/gs/dao/service
src/com/gs/dao/service/attr
src/com/gs/dao/user
src/com/gs/dao/user/attr
src/com/gs/dao/comm
src/com/gs/dao/comm/attr
src/com/gs/dao/vg
src/com/gs/dao/vg/attr
src/com/gs/dao/general
src/com/gs/dao/general/attr
src/com/gs/dao/exception
src/com/gs/elasticsearch
src/com/gs/service
src/com/gs/service/utils
src/com/gs/service/helper
src/com/gs/graph
src/com/gs/graph/gateway
src/com/gs/threads
src/com/gs/async
src/com/gs/async/test
src/com/gs/async/handler
src/com/gs/async/impl
src/com/gs/util
src/com/gs/util/xss
src/com/gs/nlp
src/com/gs/exception
src/com/gs/cassandra
src/com/gs/cassandra/dao
src/com/gs/search
src/com/gs/search/service
src/com/gs/rest
src/com/gs/rest/common
src/com/gs/rest/api
src/com/gs/rest/api/test
What the heck is all this stuff? :-)
You're probbaly not going to get one response that answers this. And you may get shut down for the question being too broad, but I will try. First off:
src/com/gs/dao/user/UserEmailDao.java
src/com/gs/dao/user/UserEmailDaoImpl.java
src/com/gs/service/UserEmailService.java
src/com/gs/service/UserEmailServiceImpl.java
That's a pretty common java pattern, You have an email service, and you split that into an interface and an implementation. You might consider it overkill (if the implementation never changes), but some of the tools being used might require interfaces. Same thing with the UserEmailDao data access object. It's pretty normal for java developers to split everything into an interface and an implementation, though it drives people using dynamic languages crazy.
As for what's generating the REST app, you need to track down where the ApiController annotation is coming from. It looks like it might be wrapper around a Spring MVC class. Post the import statement for that annotation, or just follow it your IDE.
Spring is definitely being used to wire the entire app together.
It looks like a pretty typical medium sized java application to me. From the directory structure, I doubt there is any code generation going on.
If there's a pom.xml (maven file) in the application root, that'll tell you everything you need to know about the application.
I'm attempting to retrieve a list of classes with a specific annotation in Android. I'm trying to use the Reflections library to do so. But no matter what I do, Reflections returns an empty set. Finally, I tried using Reflections.getAllTypes(), which should return all classes in a package, and it gives me the message "Couldn't find subtypes of Object. Make sure SubTypesScanner initialized to include Object class - new SubTypesScanner(false)" I have verified that I am doing so, so I looked in the code for that method and it returns that error if there are no classes in the package.
Here's an example of the code where I'm getting the error:
Reflections reflections = new Reflections(this.getClass().getPackage().getName(),
new SubTypesScanner(false));
Set<String> classes = reflections.getAllTypes(); // Throws runtime error
This should, at the very least, return the class that it is called from. I've also tried using an empty string for the package, and the answer here. Any ideas what could be causing this?
I met the same problem. Since Reflections use java assist to resolve .class file in .jar file, which isn't exist in android application, so it is not possible to use Reflections. However we could use other tool to resolve .dex and it would work
I wrote a CGM server. There I used Jackson object mapper.( Not sure I used correct library: jackson-all-1.9) After running following exception occurred.
org.codehaus.jackson.map.JsonMappingException: No serializer found for
class Content and no properties discovered to create BeanSerializer
(to avoid exception, disable
SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) )
It says to disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS.
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
Again compile time exception came.
SerializationFeature cannot be resolved to a variable.
How to solve this? I think i have used wrong library.
I had the same problem when I tried to use a good looking GCM server example found at http://hmkcode.com/android-google-cloud-messaging-tutorial/
Apart from changing the keys and IDs, the only thing I had to add to make it work is the following line in front of the "public class..." line:
#JsonAutoDetect(fieldVisibility = Visibility.ANY)
I added this line in the Content.java and the POST2GCM.java file then it was all good to go! working fine!