I'm trying to send an ArrayList of Email to a server through a Socket, but when I try to fo this I get a NotSerializableException: javafx.beans.property.SimpleObjectProperty I read on the forum that I need to implement Serializable into may Email class, which is this:
public class Email implements Serializable {
private final IntegerProperty id = new SimpleIntegerProperty();
public final IntegerProperty IDProperty() {
return this.id;
}
public final Integer getID() {
return this.IDProperty().get();
}
public final void setID(final Integer id) {
this.IDProperty().set(id);
}
private final StringProperty mittente = new SimpleStringProperty();
public final StringProperty MittenteProperty() {
return this.mittente;
}
public final String getMittente() {
return this.MittenteProperty().get();
}
public final void setMittente(final String mittente) {
this.MittenteProperty().set(mittente);
}
private final StringProperty destinatario = new SimpleStringProperty();
public final StringProperty DestinatarioProperty() {
return this.destinatario;
}
public final String getDestinatario() {
return this.DestinatarioProperty().get();
}
public final void setDestinatario(final String destinatario) {
this.DestinatarioProperty().set(destinatario);
}
private final StringProperty oggetto = new SimpleStringProperty();
public final StringProperty OggettoProperty() {
return this.oggetto;
}
public final String getOggetto() {
return this.OggettoProperty().get();
}
public final void setOggetto(final String oggetto) {
this.OggettoProperty().set(oggetto);
}
private final StringProperty testo = new SimpleStringProperty();
public final StringProperty TestoProperty() {
return this.testo;
}
public final String getTesto() {
return this.TestoProperty().get();
}
public final void setTesto(final String testo) {
this.TestoProperty().set(testo);
}
private final ObjectProperty<Date> data = new SimpleObjectProperty<Date>();
public final ObjectProperty<Date> DataProperty() {
return this.data;
}
public final Date getData() {
return this.data.get();
}
public final void setData(final Date data) {
this.data.set(data);
}
public Email (int id, String mittente, String destinatario, String oggetto, String testo, Date data) {
setID(id);
setMittente(mittente);
setDestinatario(destinatario);
setOggetto(oggetto);
setTesto(testo);
setData(data);
}
}
This is the part where I try to send it:
ObjectOutputStream objectOutput = new ObjectOutputStream(incoming.getOutputStream());
objectOutput.writeObject(arr);
But nothing changed. What should I modify?
You should implement writeObject and readObject methods in your Email class because it requires some special handling (it has non-serializable fields).
Also in readObject you need some work to initialize final fields.
At the end these two methods shold look like this:
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
out.writeInt(getID());
out.writeUTF(getMittente());
out.writeUTF(getDestinatario());
out.writeUTF(getOggetto());
out.writeUTF(getTesto());
out.writeObject(getData());
}
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
try {
Field field = this.getClass().getDeclaredField("id");
field.setAccessible(true);
field.set(this, new SimpleIntegerProperty());
field = this.getClass().getDeclaredField("mittente");
field.setAccessible(true);
field.set(this, new SimpleStringProperty());
field = this.getClass().getDeclaredField("destinatario");
field.setAccessible(true);
field.set(this, new SimpleStringProperty());
field = this.getClass().getDeclaredField("oggetto");
field.setAccessible(true);
field.set(this, new SimpleStringProperty());
field = this.getClass().getDeclaredField("testo");
field.setAccessible(true);
field.set(this, new SimpleStringProperty());
field = this.getClass().getDeclaredField("data");
field.setAccessible(true);
field.set(this, new SimpleObjectProperty<Date>());
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new IOException(e);
}
setID(in.readInt());
setMittente(in.readUTF());
setDestinatario(in.readUTF());
setOggetto(in.readUTF());
setTesto(in.readUTF());
setData((Date)in.readObject());
}
Related
I have 3 class(techspecs, packages, and features) objects where they all share the same fields. The fields are big and instead of repeating setting the fields of each field 3 times(which ends up looking like duplicates), I would like to pass the class objects into one method that uses the generic object to setting the object fields.
I tried passing the class object as a generic but then i dont have access to its members. This is what i tried
Packages packagesFeatures = new Packages();
TechSpecs techSpecsFeature = new TechSpecs();
packagesFeatures = addFeatures(Packages.class, packagesFeatures, vehFeatures);
techSpecsFeature = addFeatures(TechSpecs.class, techSpecsFeature, vehFeatures);
Then
private <T> T addFeatures(Class<T> clazz, T obj, VehicleFeature vehFeatures) {
T inst = null;
try {
inst = clazz.getDeclaredConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
}
if (inst instanceof Packages) {
obj = (T) new Packages();
}
if(inst instanceof TechSpecs){
obj = (T) new TechSpecs();
}
if(inst instanceof Features){
obj = (T) new Features();
}
//then somthing like:
//obj.setFeatureId(vehFeatures.getFeatureId());
// obj.setFeatureKey(vehFeatures.getFeatureKey());
// obj.setFeatureCode(vehFeatures.getFeatureCode());
return obj;
EDIT
Each of the 3 classes extend BaseFeatures
public abstract class BaseFeatures {
private String featureId;
private String featureKey;
private String featureCode;
private String subSectionId;
private String subSectionName;
private String featureIdName;
private Integer subSectionRank;
private Integer featureImgClassificationId;
private String featureImgClassification;
private boolean has3DAnimation;
private String sectionId;
private String searchKeys;
private String description;
private String featureName;
private double featureRank;
private String geoId;
private String ecc;
private String specSegments;
private String featureIconType;
private String featureIconText;
private double featureValue;
private boolean standardCertain;
private boolean built;
private List<String> featureKeyAnswers;
private boolean isNumeric;
private boolean adasFeature;
private List<String> icCodeAnswers;
private String featureKeyNoBrand;
private List<StyleInfo> styles;
private List<String> optionCodes;
private List<String> changeOptions;
//getters and setters.
Here is one of the classes.
public class TechSpecs extends BaseFeatures {
private String techSpecs;
public void setTechSpecs(String techSpecs) {
this.techSpecs = techSpecs;
}
public String getTechSpecs(){
return techSpecs;
}
}
All of these fields need to be set in the class object of all 3 classes
EDIT 2
VehicleFeature Class is a standalone class
#JsonInclude(JsonInclude.Include.NON_NULL)
public class VehicleFeature {
private String section;
private String subSection;
private String featureName;
private String subSectionId;
private String sectionName;
private String subSectionName;
If it were me, I would simplify your addFeatures(...) method to something like:
private <T> T addFeatures(Class<T> clazz, BaseFeatures theseFeatures) {
T obj = null;
try {
obj = clazz.getDeclaredConstructor(BaseFeatures.class).newInstance(theseFeatures);
} catch (ReflectiveOperationException roe) {
roe.printStackTrace();
}
return obj;
}
I'd add these two constructors to BaseFeatures:
public abstract class BaseFeatures{
protected String featureId;
protected String featureKey;
protected String featureCode;
/*...*/
protected BaseFeatures(String featureId, String featureKey, String featureCode){
this.featureId = featureId;
this.featureKey = featureKey;
this.featureCode = featureCode;
}
protected BaseFeatures(BaseFeatures features){
this.featureId = features.featureId ;
this.featureKey = features.featureKey;
this.featureCode = features.featureCode;
}
/*...*/
}
You can see how that implementation would actually work, here:
public class BigAssFields {
/* ... */
static public void main(String ... args){
BigAssFields bLike = new BigAssFields();
VehicleFeature vehFeatures = new VehicleFeature("what", "the actual", "Feature");
TechSpecs bigTechSpecs = bLike.addFeatures(TechSpecs.class, vehFeatures);
}
/* ... */
}
In the following file, i want to test the try method code block, using mockito. i want to test the mongo.java file using the j unit-mocking. SoaXMLLoggerRequestDTO is the model class file, and mongo.java is the class file having the method logRequestResponseXMLsWithTimeStamps.
mongo.java
public void logRequestResponseXMLsWithTimeStamps(final String requestType, final String requestXML,
final String responseXML, final long startTime, final long endTime, final long timeTaken,
final String status, final String userId, final String estimatetId) {
try {
SoaXMLLoggerRequestDTO loggerDTO = new SoaXMLLoggerRequestDTO();
loggerDTO.setRequestType(requestType);
loggerDTO.setRequestXml(requestXML);
loggerDTO.setResponseXml(responseXML);
loggerDTO.setCreatedBy(userId);
loggerDTO.setEstimateId(estimatetId + "");
loggerDTO.setStatus(status);
loggerDTO.setLatency(timeTaken);
LogExecutorService.writeToLog(new ESLoggerTask(loggerDTO, ESLoggerTask.IndexName.BNPSOALOG));
} catch (Exception e) {
LOGGER.error("Error in logRequestResponseXMLsWithTimeStamps : ", e);
throw new DAOException("Error logRequestResponseXMLs", e);
}
}
SoaXMLLoggerRequestDTO
public class SoaXMLLoggerRequestDTO extends LoggerRequestDTO{
private String requestType;
private String requestXml;
private String responseXml;
private Long latency;
private String status;
private String estimateId;
public String getRequestType() {
return requestType;
}
public void setRequestType(String requestType) {
this.requestType = requestType;
}
public String getRequestXml() {
return requestXml;
}
public void setRequestXml(String requestXml) {
this.requestXml = requestXml;
}
public String getResponseXml() {
return responseXml;
}
public void setResponseXml(String responseXml) {
this.responseXml = responseXml;
}
public Long getLatency() {
return latency;
}
public void setLatency(Long latency) {
this.latency = latency;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getEstimateId() {
return estimateId;
}
public void setEstimateId(String estimateId) {
this.estimateId = estimateId;
}
}
The following code will test the try block code.
public void test_logRequestResponseXMLsWithTimeStamps() {
estimateServicesMongoDao.logRequestResponseXMLsWithTimeStamps("ert", "rtr", "werffer",2L,0, 0, "drgfdf","sefw", null);
}
Taking the following 2 objects, I cant figure out how to make the following work.
public final *Generic SubType* getInfo(){
...
}
First the class I am working with
public class ResultEntry<Type extends ResultType>{
private final Type mType;
private final String mLabel;
private final String mInfo;
private ResultEntry(final Type t, final String label, final String info){
mType = t;
mLabel = label;
mInfo = info;
}
public static ResultEntry<ResultType> newInstance(final String label, final Number info){
return new ResultEntry<>(ResultType.NUMBER, label, info.toString());
}
public static ResultEntry<ResultType> newInstance(final String label, final Boolean info){
return new ResultEntry<>(ResultType.NUMBER, label, info.toString());
}
public static ResultEntry<ResultType> newInstance(final String label, final String info){
return new ResultEntry<>(ResultType.NUMBER, label, info);
}
public final ResultType getType(){
return mType;
}
public final String getLabel(){
return mLabel;
}
public final *Generic SybType* getInfo(){
}
}
And then enum ResultType
public enum ResultType {
STRING ("STRING"),
BOOLEAN ("BOOLEAN"),
NUMBER ("NUMBER");
private final String s;
ResultType(final String string){
s = string;
}
public final boolean isString(){
return s.equals(STRING.s);
}
public final boolean isBoolean(){
return s.equals(BOOLEAN.s);
}
public final boolean isNumber(){
return s.equals(NUMBER.s);
}
}
What I would like to do is have a way to check what mType is (String, Boolean, or Number) and then return that actual object. Something like,
public final *Generic SubType* getInfo(){
if(mType.isString()) return new String();
if(mType.isNumber()) return new Number();
if(mType.isBoolean()) return new Boolean();
}
Though obviously I would have actual information to pass back instead.
But I dont know if that is possible, and if so, I don't know how I would go about doing it. It does appear that Android is able to do it via AsyncTask.
For reference, I found most of this from This Question
I would suggest you do it like this, which doesn't convert the info values to String, i.e. mInfo is Object, not String.
public class ResultEntry<R> {
private final ResultType mType;
private final String mLabel;
private final Object mInfo;
private ResultEntry(final ResultType t, final String label, final Object info) {
this.mType = t;
this.mLabel = label;
this.mInfo = info;
}
public static ResultEntry<Number> newInstance(final String label, final Number info) {
return new ResultEntry<>(ResultType.NUMBER, label, info);
}
public static ResultEntry<Boolean> newInstance(final String label, final Boolean info) {
return new ResultEntry<>(ResultType.BOOLEAN, label, info);
}
public static ResultEntry<String> newInstance(final String label, final String info) {
return new ResultEntry<>(ResultType.STRING, label, info);
}
public final ResultType getType() {
return this.mType;
}
public final String getLabel() {
return this.mLabel;
}
#SuppressWarnings("unchecked")
public final R getInfo() {
return (R) this.mInfo;
}
}
Then you use it like this:
ResultEntry<Number> numEntry = ResultEntry.newInstance("", 5);
ResultEntry<Boolean> boolEntry = ResultEntry.newInstance("", true);
ResultEntry<String> strEntry = ResultEntry.newInstance("", "Foo");
Number numInfo = numEntry.getInfo();
Boolean boolInfo = boolEntry.getInfo();
String strInfo = strEntry.getInfo();
lets asume i have a Interface like that:
public interface User extends Element {
String getName();
String getPassword();
}
and a implementing class like that:
public class BaseUser implements User {
#Override
public String getId() {
return id;
}
#Override
public String getName() {
return name;
}
#Override
public String getPassword() {
return password;
}
public void setId(String id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
System.out.println("Set name to " + name);
}
public void setPassword(String password) {
this.password = password;
}
private String id;
private String name;
private String password;
}
Now i want to use bytebuddy to create a interceptor/proxy which catches the call onto the setter, store the changed value and call the real method also.
At the end i want to "ask" the interceptor/proxy for the called setter and the changed values.
I tried a lot considering also the tutorials but up to now i found no working solution. Maybe someone could help me pls.
And here is the Interceptor:
public class GenericInterceptor implements InvocationHandler {
#Override
#RuntimeType
public Object invoke(#This Object proxy, #Origin Method method, #AllArguments Object[] args) throws Throwable {
if (isSetter(method, args)) {
intercept(proxy, method, args);
}
return method.invoke(proxy, args);
}
}
Here is my current 'test' code:
public static void main(String[] args) {
final ByteBuddy bb = new ByteBuddy();
final GenericInterceptor interceptor = new GenericInterceptor();
bb.subclass(BaseUser.class)
.method(isDeclaredBy(BaseUser.class).and(isSetter()))
.intercept(MethodDelegation.to(interceptor))
.make()
.load(BaseUser.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER);
final BaseUser user = new BaseUser();
user.setName("my name");
}
EDIT:
public interface Element {
String getId();
}
public class GenericInterceptor<T extends Element> {
public GenericInterceptor(Class<T> type) {
this.type = type;
}
public Map<String, Object> getChanges(T obj) {
final String id = obj.getId();
return changes.get(id);
}
#RuntimeType
public void invoke(#This T proxy, #Origin Method method, #AllArguments Object[] args) throws Throwable {
System.out.println("invoke " + method.getName() + " " + Arrays.toString(args));
intercept(proxy, method, args);
}
private Object getCurrentValue(T proxy, final Field field) {
try {
return field.get(proxy);
} catch (IllegalArgumentException | IllegalAccessException e) {
return null;
}
}
private Field getSetterField(Method setter) {
final String setterName = setter.getName();
Field f = assignedFields.get(setterName);
if (f != null) return f;
final String fieldName = Character.toLowerCase(setterName.charAt(3)) + setterName.substring(4);
try {
f = type.getDeclaredField(fieldName);
if (f == null) return null;
f.setAccessible(true);
assignedFields.put(setterName, f);
return f;
} catch (NoSuchFieldException | SecurityException e) {
return null;
}
}
private void intercept(T proxy, Method setter, Object[] args) {
final Field field = getSetterField(setter);
if (field == null)
return;
final Object currentValue = getCurrentValue(proxy, field);
final Object newValue = args[0];
System.out.println("Set from " + currentValue + " to " + newValue);
final String id = proxy.getId();
Map<String, Object> changeMap = changes.get(id);
if (changeMap == null) {
changeMap = new HashMap<>();
}
changeMap.put(field.getName(), currentValue);
changes.put(id, changeMap);
}
private final Map<String, Field> assignedFields = new HashMap<>();
private final Map<String, Map<String, Object>> changes = new LinkedHashMap<>();
private final Class<T> type;
}
You can call orignal method using MethodDelegation.to(...).andThen(SuperMethodCall.INSTANCE).
public class ByteBuddyTest {
public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, InstantiationException {
GenericInterceptor interceptor = new GenericInterceptor ();
Class<?> clazz = new ByteBuddy()
.subclass(BaseUser.class)
.method(ElementMatchers.isDeclaredBy(BaseUser.class).and(ElementMatchers.isSetter()))
.intercept(SuperMethodCall.INSTANCE.andThen(MethodDelegation.to(interceptor))))
.make()
.load(ByteBuddyTest.class.getClassLoader())
.getLoaded();
BaseUser user1 = (BaseUser) clazz.getConstructors()[0].newInstance();
BaseUser user2 = (BaseUser) clazz.getConstructors()[0].newInstance();
user1.setName("user1");
user1.setPassword("password1");
user2.setName("user2");
user2.setPassword("password2");
System.out.println(interceptor.getInterceptedValue("user1", "name"));
System.out.println(interceptor.getInterceptedValue("user1", "password"));
System.out.println(interceptor.getInterceptedValue("user2", "name"));
System.out.println(interceptor.getInterceptedValue("user2", "password"));
user1.setPassword("password2");
user1.setPassword("password3");
}
public static class GenericInterceptor {
private Map<String, Object> interceptedValuesMap = new HashMap();
public void set(String obj, #This User user, #Origin Method setter) {
// assume that user name is unique so we can use it as a key in values map.
// or define equals/hashcode in GenericUser object and use it as a key directly
String setterName = setter.getName();
String propertyName = setterName.substring(3, setterName.length()).toLowerCase();
String key = user.getName() + "_" + propertyName;
System.out.println("Setting " + propertyName + " to " + obj);
System.out.println("Previous value " + interceptedValuesMap.get(key));
interceptedValuesMap.put(key, obj);
}
public Object getInterceptedValue(String userName, String fieldName) {
return interceptedValuesMap.get(userName + "_" + fieldName);
}
}
public static interface User {
String getName();
String getPassword();
}
public static class BaseUser implements User {
#Override
public String getName() {
return name;
}
#Override
public String getPassword() {
return password;
}
public void setName(String name) {
this.name = name;
}
public void setPassword(String password) {
this.password = password;
}
private String name;
private String password;
}
}
I have an object with these attributes:
public final class CaseNote {
private final Long caseNoteId;
private final Long subGroupId;
private final String title;
private final String caseNoteTypeCode;
private final Date contactDate;
private final Date completedDateTime;
private final Long personVisitId;
private final Date createdDateTime;
private final Long createdByWorkerId;
private final Long createdByTeamId;
private final List<CaseNoteDetailsDTO> noteDetails = new ArrayList<CaseNoteDetailsDTO>();
private final List<GroupMemberDetailsDTO> selectedMembers = new ArrayList<GroupMemberDetailsDTO>();
private final ReferenceProvider referenceProvider;
private final Date timeOutDate;
public CaseNote(final CaseNotesDTO caseNoteDto, final List<CaseNoteDetailsDTO> noteDetails,
final List<GroupMemberDetailsDTO> selectedMembers, final ReferenceProvider referenceProvider) {
this.caseNoteId = caseNoteDto.getCaseNoteId();
this.subGroupId = caseNoteDto.getSubGroupId();
this.title = caseNoteDto.getTitle();
this.caseNoteTypeCode = caseNoteDto.getCaseNoteTypeCode();
this.contactDate = caseNoteDto.getContactDateTime();
this.completedDateTime = caseNoteDto.getCompletedDateTime();
this.personVisitId = caseNoteDto.getPersonVisitId();
this.createdDateTime = caseNoteDto.getCreatedDateTime();
this.createdByWorkerId = caseNoteDto.getCreatedByWorkerId();
this.createdByTeamId = caseNoteDto.getCreatedByTeamId();
this.timeOutDate = caseNoteDto.getTimeOutDate();
this.noteDetails.clear();
this.selectedMembers.clear();
this.noteDetails.addAll(noteDetails);
Collections.sort(this.noteDetails, new CaseNoteDetailCreatedDateComparator());
this.selectedMembers.addAll(selectedMembers);
this.referenceProvider = referenceProvider;
}
private class CaseNoteDetailCreatedDateComparator implements Comparator<CaseNoteDetailsDTO> {
#Override
public int compare(final CaseNoteDetailsDTO firstCaseNoteDetail, final CaseNoteDetailsDTO secondCaseNoteDetail) {
return firstCaseNoteDetail.getCreatedDateTime().compareTo(secondCaseNoteDetail.getCreatedDateTime());
}
}
public Long getCaseNoteId() {
return caseNoteId;
}
public Long getSubGroupId() {
return subGroupId;
}
public String getTitle() {
return title;
}
public String getCaseNoteTypeCode() {
return caseNoteTypeCode;
}
public Date getContactDate() {
return contactDate;
}
public Date getCompletedDateTime() {
return completedDateTime;
}
public Long getPersonVisitId() {
return personVisitId;
}
public Date getCreatedDateTime() {
return createdDateTime;
}
public Long getCreatedByWorkerId() {
return createdByWorkerId;
}
public Long getCreatedByTeamId() {
return createdByTeamId;
}
public List<CaseNoteDetailsDTO> getNoteDetails() {
return Collections.unmodifiableList(noteDetails);
}
public List<GroupMemberDetailsDTO> getSelectedMembers() {
return Collections.unmodifiableList(selectedMembers);
}
public boolean isSignificant() {
boolean significantEvent = false;
for (final CaseNoteDetailsDTO detail : this.getNoteDetails()) {
significantEvent = significantEvent || detail.isSignificantEvent();
}
return significantEvent;
}
public String getCaseNoteTypeDescription() {
return referenceProvider.provide(ReferenceDomain.CASENOTE_TYPE, getCaseNoteTypeCode());
}
public CaseNoteDetailsDTO getRootNoteDetails() {
validateCaseNoteDetailsExists();
return getNoteDetails().get(0);
}
public List<CaseNoteDetailsDTO> getAppendments() {
validateCaseNoteDetailsExists();
return getNoteDetails().subList(1, getNoteDetails().size());
}
private void validateCaseNoteDetailsExists() {
if (getNoteDetails() == null || getNoteDetails().isEmpty()) {
throw new IllegalStateException("No case note details found");
}
}
public List<String> getMemberNames() {
final List<String> memberNames = new ArrayList<String>();
final List<GroupMemberDetailsDTO> selectedMembers = getSelectedMembers();
for (final GroupMemberDetailsDTO memberDetails : selectedMembers) {
memberNames.add(memberDetails.getName());
}
return memberNames;
}
public Date getTimeOutDate() {
return timeOutDate;
}
public boolean isTimedOut() {
return completedDateTime == null && new Date().after(this.timeOutDate);
}
}
From a JSP file, I would like to print the attribute 'createdWorkerId', but it's not working. I tried to print the title and it works, but not with the createdWorkerId. The line is the following:
<span class="highlighted"><%=noteClassDescription%>: <c:out value="${casenote.createdByWorkerId}"/> </span>
Should I parse the createdWorkerId to a String before or the problem is other? Any help appreciated.
Thanks.