SOLVED
I'm using DTO to map my DB to a Java object.
I had an error like this doku.eds2.dto.Transaction.getListedStatus()Ljava/lang/Character;
I have checked my Transaction.java file, it contains the getListedStatus() method.
#Column(name="listed_status", length=1)
public Character getListedStatus() {
return this.listedStatus;
}
public void setListedStatus(Character listedStatus) {
this.listedStatus = listedStatus;
}
and also my table contains this field :
Column | Type | Modifiers
listed_status | character(1) |
How can I fix this error?
Thank in advance.
This sort of error often happens if you have two different versions of a class, one with the method and one without. If the one without the method ends up in the classpath earlier than the one with, then you will get an error like this.
Make sure that your classpath does not contain any other classes of the type "doku.eds2.dto.Transaction". If you're in Eclipse, you can do this by pressing Ctrl-Shift-T and entering the class name into the search. If you get multiple matches, you probably have a class path or dependency problem.
Related
I have a class ActivitiesModel which uses Lombok's SuperBuilder.
import jakarta.validation.NotBlank;
// other imports and statements omitted for brevity.
#Data
#SuperBuilder
#NoArgsConstructor
public class ActivitiesModel {
public static final String ACTIVITIES_NOT_NULL_MESSAGE = "Activities cannot be null";
public static final String ACTIVITY_NOT_BLANK_MESSAGE = "Activity cannot be blank";
#NotNull(message = ACTIVITIES_NOT_NULL_MESSAGE)
private List<#NotBlank(message = ACTIVITY_NOT_BLANK_MESSAGE) String> activities;
}
I am using this builder to create an object of ActivitiesModel, and then validating it using Hibernate's Validator interface:
// Somewhere else in the application.
// Create an object using the builder method.
ActivitiesModel activitiesModel = ActivitiesModel.builder()
.activities(List.of("hello", "world")) // <----- Point A
.build();
// Validate the object using Hibernate's validator.
validator.validate(activitiesModel);
However, running this code gives me the following error:
java.lang.Error:
Unresolved compilation problem:
Type mismatch: cannot convert from List<String> to List<E>
The stack trace seems to be pointing at Point A.
I have tried the following approaches:
Replacing the #SuperBuilder with #Builder and #AllArgsConstructor.
Replacing the message attribute with a string literal instead of a static final variable, i.e:
private List<#NotBlank(message = "Activity cannot be blank") String> activities;
1st approach seems to fix this error, however, it's not something I can use as I need to extend the builder functionality to a subclass of ActivitiesModel. Also, this issue is also present in another abstract class, so the super builder functionality for parent classes is definitely required.
2nd approach also works in solving the error. However, going with it is a bit problematic because I then need to have the same message string in the validation test for this model class, which is something I would like to avoid as it duplicates the string.
Another thing to note is that this error only seems to occur in the presence of an annotation on the generic type parameter of the container, which is NotBlank in this case. It is not influenced by any annotations which are present directly on the field itself (NotNull in this case).
So, all in all, these are the questions that I would like to get some answers to:
Somehow, Lombok is able to figure out the types in case of a string literal but not in case of a static final String. Why is that?
Am I going about this totally wrong? The problem occurs because I'm trying to store the message string in a variable, and I'm trying to re-use the same variable at two places: the annotation's message attribute, and in the validation test for the model class. Should I not be checking for the presence of the message in my validation tests, but be checking for something else instead?
For anyone who comes across this later on, the research for this issue has led me to believe that comparing message strings in tests is not the way to go about writing validation test cases. Another downside to this approach is that you might have different validation messages for different locales. In that case, the message string itself might be a template e.g. my.message.key with its values in a ResourceBundle provided to Hibernate, i.e. files such as ValidationMessages.properties and ValidationMessages_de.properties.
In such a scenario, you could compare message for one locale in your validation test case, however, a better approach might be to check the annotation and the field for which the validation has failed. We can get both of these pieces of information via the ConstraintViolation and subsequently the ConstraintDescriptor types, provided by Hibernate. This way we can circumvent checking the message itself, but rely on the actual validation annotation which has failed.
As for the solution to this question, it seems it was a build cache issue. Cleaning maven's build cache results in this code working perfectly fine, but VSCode still seems to have an issue. For now, I will choose to ignore that.
I'm attempting to create a Xamarin Binding Library for the Android UseButton library. I created my binding project, included the .aar and set Build Action = LibraryProjectZip. As was expected, a bunch of errors popped up and I've managed to get rid of most using the Metadata.xml file, except for a bunch that follow the same pattern:
Error CS0102 The type 'CrossBridgeCommunicator' already contains a definition for 'WebViewDismiss'
I checked the CrossBridgeCommunicator class, and found it has 2 copies of about 12 events. Here's a snippet of one of these duplicates
#region "Event implementation for Com.Usebutton.Sdk.Internal.Bridge.BridgeMessageParser.IListener"
...
public event EventHandler WebViewDismiss {
add {
global::Java.Interop.EventHelper.AddEventHandler<global::Com.Usebutton.Sdk.Internal.Bridge.BridgeMessageParser.IListener, global::Com.Usebutton.Sdk.Internal.Bridge.BridgeMessageParser.IListenerImplementor>(
ref weak_implementor___SetMainBridge,
__CreateIListenerImplementor,
__v => MainBridge = __v,
__h => __h.OnWebViewDismissHandler += value);
}
...
}
...
public event EventHandler WebViewDismiss {
add {
global::Java.Interop.EventHelper.AddEventHandler<global::Com.Usebutton.Sdk.Internal.Bridge.BridgeMessageParser.IListener, global::Com.Usebutton.Sdk.Internal.Bridge.BridgeMessageParser.IListenerImplementor>(
ref weak_implementor___SetWidgetBridge,
__CreateIListenerImplementor,
__v => WidgetBridge = __v,
__h => __h.OnWebViewDismissHandler += value);
}
...
}
The only difference between them is that they access different attributes in their bodies (the "weak_implementor__"). I checked the original class in a Java decompiler and it doesn't implement any of these events; in fact, it doesn't even implement the interface. What it does have are 2 fields of this interface type. I'm guessing Xamarin creates these methods for some reason, but I don't know why or how. They don't even appear on the api.xml (nor do the fields).
I tried to change the name of the events using the Metadata.xml file, but, since these events don't even exist in the Java class, I don't know how to find them. I even tried to remove the fields using "remove-node", but am getting the warning no nodes matched. Does anyone know how can I change these events' names? Again, they come from the same interface, but are created directly on the class that has 2 fields of the interface type.
Thanks in advance.
In my project,we want manage all REST APIs errorcodes in a Enum type,like the following code:
package com.example.util
public enum ErrorType{
SUCCESS("0000", "success")
PARAMS_EMPTY("3001", "params cannot be empty")
}
The problem we encounter is if we put the class into util package,everytime we add a new error type in business spring boot app,we'll need to modify,publish and recompile the app and util project.That would be hard to maintance the util package.Basically,we prefer to maintance a relatively stable utility package.
So we are considering if there is a way that we can generate Enum type dynamiclly,we can comfigure the error information in mysql in advance,then we can load them into enum type in application boot procedure.
I'm not sure is this a good idea to dynamic generate enum type in Java,or if there is a better solution for this problem.
You can't add or remove values from an enum. Enums are complete static enumerations.
If you need to handle variable values you need to work with a standard class.
For example you can have something like the following:
public Error {
public static Error getByName(String name) {
....
}
public static Error getByCode(int code) {
....
}
}
and use it as follow:
Error myError404 = Error.getByCode(404);
Obviously this code gives you a lot of flexibility, but you cannot know in advance if a particular error code exists or not. And you can't use ide facilities related to enums.
Generating an enum would not be so useful I think, since part of the power of enums is that you can use them statically in your code - so then you have to update your code anyway.
How about adding a an exception handler to your util library that can be populated with error codes / description mappings from the database that can then translate errors/exceptions to response codes / error messages for your API? (just guessing you have an api here :-) )
Thanks for your reply,we finally decide to give up this idea.Dynamic generate an enum would not help,indeed it will add more complexity to our project,it's not a common use of enum.
Instead of this,we predefine our main error type likes user_error,system_error and db_error,etc.The specific error information will be processed in the business service.
I've been using Cucumber for dozens of Java projects so far an never encountered this issue before, so I'm a bit puzzled.
I have a simple table that I want to map to a List in my step definition.
And deal repository contains
| dealPid | closingDate | expenseCode |
| 1 | 01/06/2015 | test |
I started by creating my own POJO with only required fields, following standard camel case convention (getters/setters are omitted for clarity)
public class Deal {
private String dealPid ;
private Date closingDate ;
private String expenseCode;
}
my step definition :
#Given("^deal repository contains$")
public void deal_repository_contains(
#Format("dd/MM/yyyy") List<DEAL> deals) throws Throwable {
...
}
Fields get mapped properly and I'm getting a List with one Deal item, fine. When I go in debug, up to cucumber.runtime.xstream.LocalizedXStreams
Converter converter = converterLookup.lookupConverterForType(clazz);
I see a xStream ReflectionConverted gets selected for the Datatable parsing.
This is a legacy project, and other developers then told me there was already a class existing for this. So now I want to switch to that class, that follows really strange conventions : class name is the table name on which it's mapped in DB, and most of the attributes names are actually the column names..
So now I'm using this legacy DEAL class from another package in my step definition, so I'm expecting a List to come up, but it doesn't. I get a List but even first row gets parsed. In debug, I see the converter that gets selected is a DynamicClassWithStringAssignableConverter instead of a ReflectionConverter previously, which is why the parsed result is different in the end.
Unfortunately, I'm unable to go further in debug and understand why this implementation gets selected, as Xstream is repackaged in cucumber-jvm-deps and Eclipse gets lost (or I don't know how to attach sources correctly in that case).
I tried adding temporarily the fields I need with proper names (ie same as in my initial Deal class) in DEAL class, but it doesn't work.
Initially, DEAL class was implementing Serializable : I removed it, but still the same behavior.
It actually looks like because the class name is full upper case, a different Xstream converter gets selected...
Can it really be the root cause of the issue ?
Thanks
Just hit this very surprising behaviour myself - in my case the issue turned out to be that DynamicClassWithStringAssignableConverter.canConvert returns true if the type to be converted has a constructor that takes a single, String argument.
Work around was to remove the constructor!
I am using FreeMarker (2.3.18) to access Java variables in a custom class. When the variable name has mixed case (camel case) I'm getting an error message saying the variable does not exist.
This is a snippet of my class:
public class Student{
private String name_last, nameFirst;
public String getName_last(){
return name_last;
}
public String getNameFirst(){
return nameFirst;
}
}
In my FreeMarker template, ${passedInStudent.name_last} returns the value successfully but ${passedInStudent.nameFirst} - returns an error saying
freemarker.core.InvalidReferenceException: Expression
passedInStudent.nameFirst is undefined on line ...
Is there a known issue with using camel case variable names in FreeMarker?
Is it maybe an issue with this specific version of FreeMarker?
Is there a configuration to control it?
Is there something else wrong with the way I am accessing these variables?
You code should work. Certainly nameFirst is null, hence it counts as missing as far as FreeMarker is concerned.
OK, Problem solved!
We we're populating the record from JSON code, meaning JSON was trying to use a setter in accordance to the way properties were defined in the JSON notation (upper case, lower case, etc).
Since the setter name didn't comply with the JSON name (i.e. setNameFirst as the setter name vs. name_first in the JSON) the object was not initialized and the FreeMarker issued an error.
I set a hard coded value in the getter to eliminate the option of the object being null, when I didn't see any error - it let me to the solution.
Thank for listening :)