I created a simple JavaMailSender spring-boot application (just for fun). Here is a reference to the code on GitHub:
https://github.com/carlcorder/mail.sender
I am having a problem where inside the Email class, the "from" property is null even though I annotate it with #Value (aside from that, everything works perfectly). The class is as follows:
package com.mail.sender.domain;
import lombok.NonNull;
import org.springframework.beans.factory.annotation.Value;
#lombok.Data
#lombok.AllArgsConstructor
#lombok.NoArgsConstructor
#lombok.Builder
public class Email {
#NonNull
private String to;
#NonNull
//#Value("{spring.mail.username}") --> this is always null
private String from;
#NonNull
private String subject;
private String body;
}
I have read these posts and understand the problem is most likely related.
Difference between applicationContext.xml and spring-servlet.xml in Spring Framework
and this:
Spring #Value annotation in #Controller class not evaluating to value inside properties file
However I was still unable to get anything working. Any help would be greatly appreciated.
As Deinum, mentioned in the comment, for non spring managed class, values will not be substituted.
In your case, since you are getting from as configuration, you can move the field to MailSenderService class.
There you need to declare the field with #Value annotation.
Also as mentioned by #ndrone, the property name should be prefixed with $.
Add the below in MailSenderService and remove it from Email class
#Value("${spring.mail.username}")
private String from;
Related
I'm looking for documentation on how Jackson works with private constructors on immutable types. Using Jackson 2.9.6 and the default object mapper provided by spring boot two running with jdk-10.0.1
Given JSON:
{"a":"test"}
and given a class like:
public class ExampleValue {
private final String a;
private ExampleValue() {
this.a = null;
}
public String getA() {
return this.a;
}
}
Deserialisation (surprisingly, at least to me) seems to work.
Whereas this does not:
public class ExampleValue {
private final String a;
private ExampleValue(final String a) {
this.a = a;
}
public String getA() {
return this.a;
}
}
And this does:
public class ExampleValue {
private final String a;
#java.beans.ConstructorProperties({"a"})
private ExampleValue(final String a) {
this.a = a;
}
public String getA() {
return this.a;
}
}
My assumption is that the only way the first example can work is by using reflection to set the value of the final field (which I presume it does by java.lang.reflect.AccessibleObject.setAccessible(true).
Question 1: am I right that this is how Jackson works in this case? I presume this would have the potential to fail under a security manager which does not allow this operation?
My personal preference, therefore, would be the last code example above, since it involves less "magic" and works under a security manager. However, I have been slightly confused by various threads I've found about Lombok and constructor generation which used to generate by default #java.beans.ConstructorProperties(...) but then changed default to no longer do this and now allows one to configure it optionally using lombok.anyConstructor.addConstructorProperties=true
Some people (including in the lombok release notes for v1.16.20) suggest that:
Oracle more or less broke this annotation with the release of JDK9, necessitating this breaking change.
but I'm not precisely clear on what is meant by this, what did Oracle break? For me using JDK 10 with jackson 2.9.6 it seems to work ok.
Question 2: Is any one able to shed any light on how this annotation was broken in JDK 9 and why lombok now considers it undesirable to generate this annotation by default anymore.
Answer 1: This is exactly how it works (also to my surprise). According to the Jackson documentation on Mapper Features, the properties INFER_PROPERTY_MUTATORS, ALLOW_FINAL_FIELDS_AS_MUTATORS, and CAN_OVERRIDE_ACCESS_MODIFIERS all default to true. Therefore, in your first example, Jackson
creates an instance using the private constructor with the help of AccessibleObject#setAccessible (CAN_OVERRIDE_ACCESS_MODIFIERS),
detects a fully-accessable getter method for a (private) field, and considers the field as mutable property (INFER_PROPERTY_MUTATORS),
ignores the final on the field due to ALLOW_FINAL_FIELDS_AS_MUTATORS, and
gains access to that field using AccessibleObject#setAccessible (CAN_OVERRIDE_ACCESS_MODIFIERS).
However, I agree that one should not rely on that, because as you said a security manager could prohibit it, or Jackson's defaults may change. Furthermore, it feels "not right" to me, as I would expect that class to be immutable and the field to be unsettable.
Example 2 does not work because Jackson does not find a usable constructor (because it cannot map the field names to the parameter names of the only existing constructor, as these names are not present at runtime). #java.beans.ConstructorProperties in your third example bypasses this problem, as Jackson explicitly looks for that annotation at runtime.
Answer 2:
My interpretation is that #java.beans.ConstructorProperties is not really broken, but just cannot be assumed to be present any more with Java 9+. This is due to its membership in the java.desktop module (see, e.g., this thread for a discussion on this topic). As modularized Java applications may have a module path without this module, lombok would break such applications if it would generate this annotation by default. (Furthermore, this annotation is not available in general on the Android SDK.)
So if you have a non-modularized application or a modularized application with java.desktop on the module path, it's perfectly fine to let lombok generate the annotation by setting lombok.anyConstructor.addConstructorProperties=true, or to add the annotation manually if you are not using lombok.
Newbie question on IntelliJ plugin development.
I need to generate a parameterised class (Class with generics) given the name of the class and the name of the type parameter, but I can not find how to?
It seems PSIClass does not support generics.
Example
Given
String className = "MyClass";
String typeName = "T"
I would like to have a PSIClass that represents this:
public class MyClass<T> { ... }
The goal is to dynamically add methods to such class and eventually write the complete class to a file. The class needs to declare the Type Variable because some methods will receive/return T
Thanks!
I have found a solution in the intelliJ developer forums. It doesn't seem to be the neatest one, but it works.
I'd recommend to use
PsiFileFactory.getInstance(...).createFileFromText("ClassName.java",
JavaFileType.INSTANCE, "class ClassName { ...}"), cast the result
to PsiJavaFile and use its getClasses[0] as the result.
Here is the link to the thread:
https://intellij-support.jetbrains.com/hc/en-us/community/posts/115000089970-Create-a-new-PSIClass-with-Generic-type-parameters?page=1#community_comment_115000122164
I've a RESTeasy application using Jackson and Bean Validation. A POJO might loo like this:
public class Foo {
#Size(min = 2)
private String bar;
}
Bar is validated if the client sends the bar property. And es expected: If the client does not send the property nothing will be validated.
If the client sends an empty String I'll get a constraint violation. This may be correct but it's hard to control what the value of an empty input field really is. For instance in my angular application the field will not be present if the user did not enter anything. Once he enters and deletes something I'll have an empty String.
I thought I could configure Jacksons behavior via DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT but as answered here this is only working for POJOs not for Strings. The only ways I see is not using #Size or writing an own deserializer for Strings. Both doesn't seem to be good solutions. Anyone other ideas?
If you want to accept the empty string, you could use the #Pattern constraint matching also the empty string: #Pattern(regexp = "^$|(.){2}") or #Pattern(regexp = "^$|...
The alternative is to write your own custom constraint.
In my Google Web Toolkit project, I got the following error:
com.google.gwt.user.client.rpc.SerializationException: Type ‘your.class.Type’ was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.
What are the possible causes of this error?
GWT keeps track of a set of types which can be serialized and sent to the client. your.class.Type apparently was not on this list. Lists like this are stored in .gwt.rpc files. These lists are generated, so editing these lists is probably useless. How these lists are generated is a bit unclear, but you can try the following things:
Make sure your.class.Type implements java.io.Serializable
Make sure your.class.Type has a public no-args constructor
Make sure the members of your.class.Type do the same
Check if your program does not contain collections of a non-serializable type, e.g. ArrayList<Object>. If such a collection contains your.class.Type and is serialized, this error will occur.
Make your.class.Type implement IsSerializable. This marker interface was specifically meant for classes that should be sent to the client. This didn't work for me, but my class also implemented Serializable, so maybe both interfaces don't work well together.
Another option is to create a dummy class with your.class.Type as a member, and add a method to your RPC interface that gets and returns the dummy. This forces the GWT compiler to add the dummy class and its members to the serialization whitelist.
I'll also add that if you want to use a nested class, use a static member class.
I.e.,
public class Pojo {
public static class Insider {
}
}
Nonstatic member classes get the SerializationException in GWT 2.4
I had the same issue in a RemoteService like this
public List<X> getX(...);
where X is an interface. The only implementation did conform to the rules, i.e. implements Serializable or IsSerializable, has a default constructor, and all its (non-transient and non-final) fields follow those rules as well.
But I kept getting that SerializationException until I changed the result type from List to X[], so
public X[] getX(...);
worked. Interestingly, the only argument being a List, Y being an interface, was no problem at all...
I have run into this problem, and if you per chance are using JPA or Hibernate, this can be a result of trying to return the query object and not creating a new object and copying your relavant fields into that new object. Check the following out, which I saw in a google group.
#SuppressWarnings("unchecked")
public static List<Article> getForUser(User user)
{
List<Article> articles = null;
PersistenceManager pm = PMF.get().getPersistenceManager();
try
{
Query query = pm.newQuery(Article.class);
query.setFilter("email == emailParam");
query.setOrdering("timeStamp desc");
query.declareParameters("String emailParam");
List<Article> results = (List<Article>) query.execute(user.getEmail
());
articles = new ArrayList<Article>();
for (Article a : results)
{
a.getEmail();
articles.add(a);
}
}
finally
{
pm.close();
}
return articles;
}
this helped me out a lot, hopefully it points others in the right direction.
Looks like this question is very similar to what IsSerializable or not in GWT?, see more links to related documentation there.
When your class has JDO annotations, then this fixed it for me (in addition to the points in bspoel's answer) : https://stackoverflow.com/a/4826778/1099376
Resolving a class that has multiple constructors with NInject doesn't seem to work.
public class Class1 : IClass
{
public Class1(int param) {...}
public Class1(int param2, string param3) { .. }
}
the following doesn’t seem to work:
IClass1 instance =
IocContainer.Get<IClass>(With.Parameters.ConstructorArgument(“param”, 1));
The hook in the module is simple, and worked before I added the extra constructor:
Bind().To();
The reason that it doesn't work is that manually supplied .ctor arguments are not considered in the .ctor selection process. The .ctors are scored according to how many parameters they have of which there is a binding on the parameter type. During activation, the manually supplied .ctor arguments are applied. Since you don't have bindings on int or string, they are not scored. You can force a scoring by adding the [Inject] attribute to the .ctor you wish to use.
The problem you're having is that Ninject selects .ctors based on the number of bound parameters available to it. That means that Ninject fundamentally doesn't understand overloading.
You can work around this problem by using the .ToConstructor() function in your bindings and combining it with the .Named() function. That lets you create multiple bindings for the same class to different constructors with different names. It's a little kludgy, but it works.
I maintain my own software development blog so this ended up being a post on it. If you want some example code and a little more explanation you should check it out.
http://www.nephandus.com/2013/05/10/overloading-ninject/