optaplanner can't find annotated planning varible - optaplanner

I want to delete or add some ProblemFacts to the solver while the solver solve my patient admission solution.
In the documentation from optaplanner I can add about solver.addProblemFactChange some ProblemFacs, but it doesn't work in my PAS example.
Here is a snippet of my code of PatientAdmissionScheduleGenerator
public void addBedDesignation(final BedDesignation bedDesignation){
this.solver.addProblemFactChange(scoreDirector -> {
PatientAdmissionScheduleSolution patientAdmissionScheduleSolution = scoreDirector.getWorkingSolution();
patientAdmissionScheduleSolution.getBedDesignationList().add(bedDesignation);
});
}
public void deleteBedDesignation(final BedDesignation bedDesignation){
// Neues Problem dem Solver zuführen
this.solver.addProblemFactChange(scoreDirector -> {
// Erstelle eine neue PAS-Solution auf Basis der gerade läuft
PatientAdmissionScheduleSolution patientAdmissionScheduleSolution = scoreDirector.getWorkingSolution();
// Erstelle eine neue Bettzuweisung auf Basis der
BedDesignation workingBedDesignation = scoreDirector.lookUpWorkingObject(bedDesignation);
for(BedDesignation designation : patientAdmissionScheduleSolution.getBedDesignationList()){
if(designation.equals(bedDesignation)){
scoreDirector.beforeVariableChanged(designation, "Bed");
designation = null;
scoreDirector.afterVariableChanged(designation,"Bed");
}
}
ArrayList<BedDesignation> bedDesignationArrayList = new ArrayList<>(patientAdmissionScheduleSolution.getBedDesignationList());
patientAdmissionScheduleSolution.setBedDesignationList(bedDesignationArrayList);
scoreDirector.beforeProblemFactRemoved(workingBedDesignation);
bedDesignationArrayList.remove(workingBedDesignation);
scoreDirector.afterProblemFactRemoved(workingBedDesignation);
scoreDirector.triggerVariableListeners();
});
}
Here is a snippet of my changed Object BedDesignation
#PlanningVariable(nullable = true, valueRangeProviderRefs = {"bedRange"}, strengthComparatorClass = BedStrengthComparator.class)
public Bed getBed() {
return bed;
}
An here is my error message when I want to delete a BedDesignation Object
Exception in thread "main" java.lang.IllegalArgumentException: The variableName (Bed) for entityClass (class pas.entity.domain.BedDesignation) exists as a property (getter/setter) on that class, but not as an annotated as a planning variable.
Check if your planning entity's getter has the annotation PlanningVariable (or a shadow variable annotation).
I have annotated bed as PlanningVariable. What is wrong?

The error message is blaming the wrong reason. I created a jira.
Use "bed" instead of "Bed".

Related

Migration from Spring Batch 3 to 4

I'm trying to migrate from Spring Batch 3.0.6 to 4.1.1.
I'm stuck handling Spring Batch's execution context data as explained here.
What I would like is update tables batch_step_execution_context and batch_step_execution_context as follows, for each record :
unserialize context data using the deprecated XStreamExecutionContextStringSerializer
serialize the java object obtained using a jackson ObjectMapper
update the table using this new string
It has worked for some records and I could run Spring Batch 4. But for some jobs, the new string is not deserializable as a ExecutionContext.
Here is an example of such a string :
{
"setMoisAffaires":[
{
"premierJourDuMois":{
"date":1257030000000,
"stringFromDatePatternAmericain":"2009-11-01",
"hour":0,
"year":2009,
"dayOfMonth":1,
"dayOfWeek":7,
"dateString":"20091101",
"monthOfYear":11,
"minuteOfHour":0,
"secondOfMinute":0
},
"date":1257030000000,
"stringFromDatePatternAmericain":"2009-11-01",
"hour":0,
"year":2009,
"dayOfMonth":1,
"dayOfWeek":7,
"dateString":"200911",
"monthOfYear":11,
"minuteOfHour":0,
"secondOfMinute":0
},
//a lot of records like the previous...
],
"batch.taskletType":"com.sun.proxy.$Proxy57",
"batch.stepType":"org.springframework.batch.core.step.tasklet.TaskletStep"
}
Here is the trace when I try to do : ExecutionContext a = objectMapper.readValue(objectMapper.writeValueAsString(javaObject),ExecutionContext.class);
Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "setMoisAffaires" (class org.springframework.batch.item.ExecutionContext), not marked as ignorable (one known property: "dirty"])
at [Source: (String)"{"setMoisAffaires":[{"prem...[truncated 15163 chars]; line: 1, column: 21] (through reference chain: org.springframework.batch.item.ExecutionContext["setMoisAffaires"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:823)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1153)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1589)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1567)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:294)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3004)
Here is a unit test to reproduce the problem :
package springBatch4Migration;
import static org.junit.Assert.assertNotNull;
import java.io.ByteArrayInputStream;
import org.junit.Test;
import org.springframework.batch.core.repository.dao.XStreamExecutionContextStringSerializer;
import org.springframework.batch.item.ExecutionContext;
import com.fasterxml.jackson.databind.ObjectMapper;
public class SerializeTest {
#Test
public void test() throws Exception {
String oldJson = "{\"map\":[{\"entry\":[{\"string\":[\"batch.stepType\",\"org.springframework.batch.core.step.tasklet.TaskletStep\"]},{\"string\":[\"batch.taskletType\",\"com.sun.proxy.$Proxy56\"]},{\"string\":\"setMoisAffaires\",\"set\":[{\"tools.date.dates.Mois\":[{\"dateLocale\":{\"iLocalMillis\":1264982400000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#resolves-to\":\"org.joda.time.chrono.ISOChronology$Stub\",\"#serialization\":\"custom\",\"org.joda.time.chrono.ISOChronology$Stub\":{\"org.joda.time.UTCDateTimeZone\":{\"#resolves-to\":\"org.joda.time.DateTimeZone$Stub\",\"#serialization\":\"custom\",\"org.joda.time.DateTimeZone$Stub\":{\"string\":\"UTC\"}}}}},\"categorie\":\"MOIS\",\"dateAsString\":201002},{\"dateLocale\":{\"iLocalMillis\":1312156800000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201108},{\"dateLocale\":{\"iLocalMillis\":1288569600000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201011},{\"dateLocale\":{\"iLocalMillis\":1285891200000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201010},{\"dateLocale\":{\"iLocalMillis\":1243814400000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":200906},{\"dateLocale\":{\"iLocalMillis\":1257033600000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":200911},{\"dateLocale\":{\"iLocalMillis\":1277942400000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201007},{\"dateLocale\":{\"iLocalMillis\":1249084800000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":200908},{\"dateLocale\":{\"iLocalMillis\":1320105600000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201111},{\"dateLocale\":{\"iLocalMillis\":1283299200000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201009},{\"dateLocale\":{\"iLocalMillis\":1328054400000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201202},{\"dateLocale\":{\"iLocalMillis\":1325376000000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201201},{\"dateLocale\":{\"iLocalMillis\":1296518400000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201102},{\"dateLocale\":{\"iLocalMillis\":1306886400000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201106},{\"dateLocale\":{\"iLocalMillis\":1267401600000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201003},{\"dateLocale\":{\"iLocalMillis\":1251763200000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":200909},{\"dateLocale\":{\"iLocalMillis\":1262304000000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201001},{\"dateLocale\":{\"iLocalMillis\":1280620800000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201008},{\"dateLocale\":{\"iLocalMillis\":1270080000000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201004},{\"dateLocale\":{\"iLocalMillis\":1317427200000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201110},{\"dateLocale\":{\"iLocalMillis\":1272672000000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201005},{\"dateLocale\":{\"iLocalMillis\":1304208000000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201105},{\"dateLocale\":{\"iLocalMillis\":1233446400000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":200902},{\"dateLocale\":{\"iLocalMillis\":1254355200000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":200910},{\"dateLocale\":{\"iLocalMillis\":1246406400000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":200907},{\"dateLocale\":{\"iLocalMillis\":1309478400000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201107},{\"dateLocale\":{\"iLocalMillis\":1259625600000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":200912},{\"dateLocale\":{\"iLocalMillis\":1238544000000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":200904},{\"dateLocale\":{\"iLocalMillis\":1314835200000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201109},{\"dateLocale\":{\"iLocalMillis\":1330560000000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201203},{\"dateLocale\":{\"iLocalMillis\":1241136000000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":200905},{\"dateLocale\":{\"iLocalMillis\":1322697600000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201112},{\"dateLocale\":{\"iLocalMillis\":1301616000000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201104},{\"dateLocale\":{\"iLocalMillis\":1275350400000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201006},{\"dateLocale\":{\"iLocalMillis\":1293840000000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201101},{\"dateLocale\":{\"iLocalMillis\":1235865600000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":200903},{\"dateLocale\":{\"iLocalMillis\":1291161600000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201012},{\"dateLocale\":{\"iLocalMillis\":1298937600000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201103}]}]}]}]}";
/*
* Unserializing oldJson to a Java object...
*/
XStreamExecutionContextStringSerializer oldSerializer = new XStreamExecutionContextStringSerializer();
oldSerializer.init();
ByteArrayInputStream oldInputStream = new ByteArrayInputStream(oldJson.getBytes());
Object javaObject = oldSerializer.deserialize(oldInputStream);
/*
* Serializing back to a new Json string using Jackson...
*/
ObjectMapper newSerializer = new ObjectMapper();
ExecutionContext a = newSerializer.readValue(newSerializer.writeValueAsString(javaObject),ExecutionContext.class);
assertNotNull(a);
}
}
And here is what I get if I try to run a job using such data :
ERROR - CommandLineJobRunner:367 - Job Terminated in error: Unable to deserialize the execution context
java.lang.IllegalArgumentException: Unable to deserialize the execution context
at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao$ExecutionContextRowMapper.mapRow(JdbcExecutionContextDao.java:328)
at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao$ExecutionContextRowMapper.mapRow(JdbcExecutionContextDao.java:312)
at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:94)
at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:61)
at org.springframework.jdbc.core.JdbcTemplate$1.doInPreparedStatement(JdbcTemplate.java:679)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:617)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:669)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:700)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:712)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:768)
at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao.getExecutionContext(JdbcExecutionContextDao.java:129)
at org.springframework.batch.core.explore.support.SimpleJobExplorer.getStepExecutionDependencies(SimpleJobExplorer.java:210)
at org.springframework.batch.core.explore.support.SimpleJobExplorer.getJobExecutions(SimpleJobExplorer.java:87)
at org.springframework.batch.core.JobParametersBuilder.getNextJobParameters(JobParametersBuilder.java:266)
at org.springframework.batch.core.launch.support.CommandLineJobRunner.start(CommandLineJobRunner.java:357)
at org.springframework.batch.core.launch.support.CommandLineJobRunner.main(CommandLineJobRunner.java:564)
at fr.mycompany.myapp.commun.batch.CommandLineJobRunnerTest.runJob(CommandLineJobRunnerTest.java:180)
at fr.mycompany.myapp.commun.batch.CommandLineJobRunnerTest.execute(CommandLineJobRunnerTest.java:496)
at fr.mycompany.myapp.commun.batch.CommandLineJobRunnerTest.main(CommandLineJobRunnerTest.java:529)
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Unexpected token (START_OBJECT), expected VALUE_STRING: need JSON String that contains type id (for subtype of java.lang.Object)
at [Source: (ByteArrayInputStream); line: 1, column: 21] (through reference chain: java.util.HashMap["setMoisAffaires"])
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
at com.fasterxml.jackson.databind.DeserializationContext.wrongTokenException(DeserializationContext.java:1499)
at com.fasterxml.jackson.databind.DeserializationContext.reportWrongTokenException(DeserializationContext.java:1274)
at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._locateTypeId(AsArrayTypeDeserializer.java:151)
at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._deserialize(AsArrayTypeDeserializer.java:96)
at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer.deserializeTypedFromAny(AsArrayTypeDeserializer.java:71)
at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserializeWithType(UntypedObjectDeserializer.java:712)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringKeyMap(MapDeserializer.java:529)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:364)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:29)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3077)
at org.springframework.batch.core.repository.dao.Jackson2ExecutionContextStringSerializer.deserialize(Jackson2ExecutionContextStringSerializer.java:70)
at org.springframework.batch.core.repository.dao.Jackson2ExecutionContextStringSerializer.deserialize(Jackson2ExecutionContextStringSerializer.java:50)
at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao$ExecutionContextRowMapper.mapRow(JdbcExecutionContextDao.java:325)
... 18 more
Here is an example of a step using such setMoisAffaires :
<bean id="jobname.jobstep" parent="jobItemParent"
class="fr.mycompany.myapp.collecte.batch.jobname.jobstep" scope="step">
<property name="setMoisAffaires" value="#{stepExecutionContext['setMoisAffaires']}" />
</bean>
What has been serialized with XStream is not necessarily deserializable with Jackson. So I'm not sure how you can solve this issue. See breaking change note here.
EDIT: After adding a minimal complete verifiable example
The XStreamExecutionContextStringSerializer#deserialize returns a Map<String, Object> of the key/value pairs of the old execution context. I would this map directly as input to the Jackson serializer instead of marshalling it to a String and then creating it back from a String. Here is how I updated the test:
import static org.junit.Assert.assertNotNull;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.springframework.batch.core.repository.dao.Jackson2ExecutionContextStringSerializer;
import org.springframework.batch.core.repository.dao.XStreamExecutionContextStringSerializer;
public class SerializeTest {
#Test
public void test() throws Exception {
String oldJson = "{\"map\":[{\"entry\":[{\"string\":[\"batch.stepType\",\"org.springframework.batch.core.step.tasklet.TaskletStep\"]},{\"string\":[\"batch.taskletType\",\"com.sun.proxy.$Proxy56\"]},{\"string\":\"setMoisAffaires\",\"set\":[{\"tools.date.dates.Mois\":[{\"dateLocale\":{\"iLocalMillis\":1264982400000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#resolves-to\":\"org.joda.time.chrono.ISOChronology$Stub\",\"#serialization\":\"custom\",\"org.joda.time.chrono.ISOChronology$Stub\":{\"org.joda.time.UTCDateTimeZone\":{\"#resolves-to\":\"org.joda.time.DateTimeZone$Stub\",\"#serialization\":\"custom\",\"org.joda.time.DateTimeZone$Stub\":{\"string\":\"UTC\"}}}}},\"categorie\":\"MOIS\",\"dateAsString\":201002},{\"dateLocale\":{\"iLocalMillis\":1312156800000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201108},{\"dateLocale\":{\"iLocalMillis\":1288569600000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201011},{\"dateLocale\":{\"iLocalMillis\":1285891200000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201010},{\"dateLocale\":{\"iLocalMillis\":1243814400000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":200906},{\"dateLocale\":{\"iLocalMillis\":1257033600000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":200911},{\"dateLocale\":{\"iLocalMillis\":1277942400000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201007},{\"dateLocale\":{\"iLocalMillis\":1249084800000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":200908},{\"dateLocale\":{\"iLocalMillis\":1320105600000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201111},{\"dateLocale\":{\"iLocalMillis\":1283299200000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201009},{\"dateLocale\":{\"iLocalMillis\":1328054400000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201202},{\"dateLocale\":{\"iLocalMillis\":1325376000000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201201},{\"dateLocale\":{\"iLocalMillis\":1296518400000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201102},{\"dateLocale\":{\"iLocalMillis\":1306886400000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201106},{\"dateLocale\":{\"iLocalMillis\":1267401600000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201003},{\"dateLocale\":{\"iLocalMillis\":1251763200000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":200909},{\"dateLocale\":{\"iLocalMillis\":1262304000000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201001},{\"dateLocale\":{\"iLocalMillis\":1280620800000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201008},{\"dateLocale\":{\"iLocalMillis\":1270080000000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201004},{\"dateLocale\":{\"iLocalMillis\":1317427200000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201110},{\"dateLocale\":{\"iLocalMillis\":1272672000000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201005},{\"dateLocale\":{\"iLocalMillis\":1304208000000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201105},{\"dateLocale\":{\"iLocalMillis\":1233446400000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":200902},{\"dateLocale\":{\"iLocalMillis\":1254355200000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":200910},{\"dateLocale\":{\"iLocalMillis\":1246406400000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":200907},{\"dateLocale\":{\"iLocalMillis\":1309478400000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201107},{\"dateLocale\":{\"iLocalMillis\":1259625600000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":200912},{\"dateLocale\":{\"iLocalMillis\":1238544000000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":200904},{\"dateLocale\":{\"iLocalMillis\":1314835200000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201109},{\"dateLocale\":{\"iLocalMillis\":1330560000000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201203},{\"dateLocale\":{\"iLocalMillis\":1241136000000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":200905},{\"dateLocale\":{\"iLocalMillis\":1322697600000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201112},{\"dateLocale\":{\"iLocalMillis\":1301616000000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201104},{\"dateLocale\":{\"iLocalMillis\":1275350400000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201006},{\"dateLocale\":{\"iLocalMillis\":1293840000000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201101},{\"dateLocale\":{\"iLocalMillis\":1235865600000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":200903},{\"dateLocale\":{\"iLocalMillis\":1291161600000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201012},{\"dateLocale\":{\"iLocalMillis\":1298937600000,\"iChronology\":{\"#class\":\"org.joda.time.chrono.ISOChronology\",\"#reference\":\"..\\/..\\/..\\/tools.date.dates.Mois\\/dateLocale\\/iChronology\"}},\"categorie\":\"MOIS\",\"dateAsString\":201103}]}]}]}]}";
/*
* Unserializing oldJson to a Java object...
*/
XStreamExecutionContextStringSerializer oldSerializer = new XStreamExecutionContextStringSerializer();
oldSerializer.init();
ByteArrayInputStream oldInputStream = new ByteArrayInputStream(oldJson.getBytes());
Map<String, Object> javaObject = oldSerializer.deserialize(oldInputStream);
/*
* Serializing back to a new Json string using Jackson...
*/
ObjectMapper newSerializer = new ObjectMapper();
String newJson = newSerializer.writeValueAsString(javaObject);
assertNotNull(newJson);
System.out.println("newJson = " + newJson);
/*
* Or more correctly
*/
Jackson2ExecutionContextStringSerializer stringSerializer = new Jackson2ExecutionContextStringSerializer();
ByteArrayOutputStream out = new ByteArrayOutputStream();
stringSerializer.serialize(javaObject, out);
newJson = new String(out.toByteArray());
assertNotNull(newJson);
System.out.println("newJson = " + newJson);
}
}
Hope this helps.

cross-file reference in xtext

I created a new DSL by using xtext as follows.
(Actually I will access the DSL on RCP application.)
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
Configuration:
components+=(Component)*;
Component:
'Component' name=ID
'{'
(('display' display=STRING) &
('dependency' dependency=[Component|ID])?)
'}'
;
I have two files:
sample1.mydsl
Component comp1 {
display "comp1"
dependency comp2
}
sampl2.mydsl
Component comp2 {
display "comp2"
}
To check the reference from another file,
I tried to run a test code as standalone but I couldn't get the eobject exactly.
test code
public static final void main(String arg[]) {
new org.eclipse.emf.mwe.utils.StandaloneSetup().setPlatformUri("../");
Injector injector = new MyDslStandaloneSetup().createInjectorAndDoEMFRegistration();
XtextResourceSet resourceSet = injector.getInstance(XtextResourceSet.class);
resourceSet.addLoadOption(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE);
File file=new File("/Users/nuckee/Work/temp/mydsl/sample1.mydsl");
Resource resource = resourceSet.getResource(
URI.createURI(file.toURI().toString()), true);
Configuration config = (Configuration) resource.getContents().get(0);
Component comp1 = config.getComponents().get(0);
if (comp1 != null) {
System.out.println("configuration displayed name : " + comp1.getDisplay());
Component dep = comp1.getDependency() ;
if (dep != null) {
System.out.println("dep : " + dep);
System.out.println("dep displayed name : " + dep.getDisplay());
}
}
}
result
configuration displayed name : comp1
dep : org.xtext.example.mydsl.myDsl.impl.ComponentImpl#61544ae6 (eProxyURI: file:/Users/nuckee/Work/temp/mydsl/sample1.mydsl#|0)
dep displayed name : null
How can exactly I get the display of "comp2" from another file?
I Hope someone can help me solve it. Thanks.
You have to load all model files into the resourceset. Xtext does not do auto file discovery

Error occurred creating story: "Cannot parse object reference from", Rally

I am trying to create user stories in rally by java. Am failing to get response and it throwing " Cannot parse object reference from ".
Brief on my rally : Let assume I have Project name "Characters" and its has subs as A, B, C, D. I have to create my user stories in C. Is my following code correct in this prospect? Can anyone please help?
package samplerally;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import com.google.gson.JsonObject;
import com.rallydev.rest.RallyRestApi;
import com.rallydev.rest.request.CreateRequest;
import com.rallydev.rest.request.GetRequest;
import com.rallydev.rest.response.CreateResponse;
import com.rallydev.rest.util.Ref;
public class CreateStory {
public static void main(String[] args) throws URISyntaxException,IOException {
String host = "https://rally1.rallydev.com";
String username = "name#comp.com";
String password = "password";
String wsapiVersion = "v2.0";
String applicationName = "C";
RallyRestApi restApi = new RallyRestApi(new URI(host),username,password);
restApi.setWsapiVersion(wsapiVersion);
restApi.setApplicationName(applicationName);
try {
for (int i = 0; i < 3; i++) {
// Add a story
System.out.println("Creating a story...");
JsonObject newStory = new JsonObject();
newStory.addProperty("Name", "my story");
newStory.addProperty("Project", "Characters");
CreateRequest createRequest = new CreateRequest("hierarchicalrequirement", newStory);
CreateResponse createResponse = restApi.create(createRequest);
System.out.println("Response ::: "+createResponse.wasSuccessful());
if (createResponse.wasSuccessful()) {
System.out.println(String.format("Created %s",createResponse.getObject().get("_ref").getAsString()));
// Read story
String ref = Ref.getRelativeRef(createResponse.getObject().get("_ref").getAsString());
System.out.println(String.format("\nReading Story %s...",ref));
GetRequest getRequest = new GetRequest(ref);
} else {
String[] createErrors;
createErrors = createResponse.getErrors();
System.out.println("Error occurred creating story: ");
for (int j = 0; j < createErrors.length; j++) {
System.out.println(createErrors[j]);
}
}
}
} finally {
// Release all resources
restApi.close();
}
}
}
And I am getting error as :
Creating a story...
Response ::: false
Error occurred creating story:
Could not read: Cannot parse object reference from "BSS HWSE Team Columbia"
Creating a story...
Response ::: false
Error occurred creating story:
Could not read: Cannot parse object reference from "BSS HWSE Team Columbia"
Creating a story...
Response ::: false
Error occurred creating story:
Could not read: Cannot parse object reference from "BSS HWSE Team Columbia"
Picked up JAVA_TOOL_OPTIONS: -agentlib:jvmhook
Picked up _JAVA_OPTIONS: -Xrunjvmhook -Xbootclasspath/a:"C:\Program Files\HP\Unified Functional Testing\bin\java_shared\classes";"C:\Program Files\HP\Unified Functional Testing\bin\java_shared\classes\jasmine.jar"
Please help. New to rally. Thanks in advance
When setting reference fields such as Project, Iteration, Release, WorkProduduct, Parent, etc that point to full objects use the reference,and not the Name.
Find out the unique ObjectID of the Project "C", e.g. 123456.
Replace:
newStory.addProperty("Project", "Characters");
with
newStory.addProperty("Project", "/project/123456");
To find ObjectID of a project you may either query by its name in WS API, or look at the URL of one of Rally pages in the address bar, while in that project, e.g. URL of a Backlog page: https://rally1.rallydev.com/#/123456/backlog
If there is a d or u appended to ObjectID string, e.g. 123456d, do not include it in string. In the URL it indicates if you are currently scoping up or down.

declare ITD static method on multiple types

I would like to declare a static method (like void main(String..args)) on every subtype of my App class.
public aspect Aspects pertypewithin(App+) {
protected Class appClass;
after() : staticinitialization(App+) && !staticinitialization(App) {
StaticPart point = thisJoinPointStaticPart;
Signature signature = point.getSignature();
Class declaringType = signature.getDeclaringType();
this.appClass = declaringType;
}
public static void App.main(String...args) {
// how do i make this appear on every subtype of App, not just App
}
}
Is this possible with AspectJ?
The usual pattern for adding a set of non-static methods to multiple classes is to define an interface + implementing methods within an aspect and use declare parents in order to make the target classes implement the interface.
Unfortunately this does not work for static methods like main because static methods cannot be defined via an interface. On the other hand, if you have a class MyApp extends App you can call java -cp ... MyApp, i.e. its parent main method will automatically be used.
Now let us assume that for some reason you want the contents of the generated main methods to be somehow different. In this case you really need to generate one method per class. For that purpose you can use a new feature introduced in AspectJ 1.8.2 and described in the release notes: annotation processing support. Here is some self-consistent sample code. I compiled it from the command line because from Eclipse I failed to get it running according to AspectJ maintainer Andy Clement's description.
Okay, let's say we have two project directories somewhere in a base directory called java-src. The directory layout be like this:
java-src
SO_AJ_ITD_AddMainMethodToAllSubclasses_AJ
src\de\scrum_master\app\App.java
src\de\scrum_master\app\BarApp.java
src\de\scrum_master\app\FooApp.java
compile_run.bat
SO_AJ_ITD_AddMainMethodToAllSubclasses_APT
src\de\scrum_master\app\EntryPoint.java
src\de\scrum_master\aspect\EntryPointProcessor.java
src\META-INF\services\javax.annotation.processing.Processor
In project SO_AJ_ITD_AddMainMethodToAllSubclasses_AJ we have our Java classes:
package de.scrum_master.app;
#EntryPoint
public class App {
public void doSomething() {
System.out.println("Doing something");
}
}
package de.scrum_master.app;
public class FooApp extends App {
public void doFoo() {
System.out.println("Doing foo");
}
public int add(int a, int b) {
return a + b;
}
}
package de.scrum_master.app;
public class BarApp extends App {
public void doBar() {
System.out.println("Doing bar");
}
public int multiply(int a, int b) {
return a * b;
}
}
In project SO_AJ_ITD_AddMainMethodToAllSubclasses_APT we have our marker annotation, the annotation processor and processor description file for the META-INF directory of our processor.jar:
Please note: The annotation is #Inherited when applied to classes. This is important in order to make the annotation processor find it.
package de.scrum_master.app;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.TYPE)
#Inherited
public #interface EntryPoint {}
The annotation processor creates one aspect per annotated class. Each aspect does the following:
Add a main method which
instantiates an object of the target class,
always calls the base method doSomething() upon the target instance,
searches the target class for other simple non-static methods without parameters and calls these methods, just so as to show some fancy and dynamic stuff and make the resulting aspects look a bit different.
package de.scrum_master.aspect;
import java.io.*;
import javax.tools.*;
import java.util.*;
import javax.annotation.processing.*;
import javax.lang.model.*;
import javax.lang.model.element.*;
import de.scrum_master.app.EntryPoint;
#SupportedAnnotationTypes(value = { "*" })
#SupportedSourceVersion(SourceVersion.RELEASE_7)
public class EntryPointProcessor extends AbstractProcessor {
private Filer filer;
#Override
public void init(ProcessingEnvironment env) {
filer = env.getFiler();
}
#Override
public boolean process(Set<? extends TypeElement> elements, RoundEnvironment env) {
// Discover elements marked with #EntryPoint
for (Element element : env.getElementsAnnotatedWith(EntryPoint.class)) {
// Skip non-class elements
if (element.getKind() != ElementKind.CLASS)
continue;
String packageName = element.getEnclosingElement().toString().substring(8);
String className = element.getSimpleName().toString();
String aspectName = "MainMethodAspect_" + className;
// For each marked class, create an aspect adding a 'main' method
String aspectSource = createAspectSource(element, packageName, className, aspectName);
writeAspectSourceToDisk(element, packageName, aspectName, aspectSource);
}
return true;
}
private String createAspectSource(Element element, String packageName, String className, String aspectName) {
String variableName = className.substring(0, 1).toLowerCase() + className.substring(1);
StringBuilder aspectSource = new StringBuilder()
.append("package " + packageName + ";\n\n")
.append("public aspect " + aspectName + " {\n")
.append(" public static void " + className + ".main(String[] args) {\n")
.append(" " + className + " " + variableName + " = new " + className + "();\n")
.append(" " + variableName + ".doSomething();\n");
for (Element childElement : element.getEnclosedElements()) {
// Skip everything which is not a non-static method
if (childElement.getKind() != ElementKind.METHOD || childElement.getModifiers().contains(Modifier.STATIC))
continue;
ExecutableElement method = (ExecutableElement) childElement;
// Skip methods with parameters or named 'doSomething'
if (!method.getParameters().isEmpty() || method.getSimpleName().toString().equals("doSomething"))
continue;
// Add call to found method
aspectSource.append(" " + variableName + "." + method.getSimpleName() + "();\n");
}
aspectSource
.append(" }\n")
.append("}\n");
return aspectSource.toString();
}
private void writeAspectSourceToDisk(Element element, String packageName, String aspectName, String aspectSource) {
try {
JavaFileObject file = filer.createSourceFile(packageName + "." + aspectName, element);
file.openWriter().append(aspectSource).close();
System.out.println("Generated aspect " + packageName + "." + aspectName + " to advise " + element);
} catch (IOException ioe) {
// Message "already created" can appear if processor runs more than once
if (!ioe.getMessage().contains("already created"))
ioe.printStackTrace();
}
}
}
The processor description file src\META-INF\services\javax.annotation.processing.Processor for APT looks like this:
de.scrum_master.aspect.EntryPointProcessor
How to compile and run: Last, but not least here is a (Windows) batch file SO_AJ_ITD_AddMainMethodToAllSubclasses_AJ\compile_run.bat which
compiles the APT project and packages it into a JAR,
compiles the other project including APM aspect code generation and finally
runs each of the three Java classes, testing if their main methods actually work as expected:
#echo off
set SRC_PATH=C:\Users\Alexander\Documents\java-src
set ASPECTJ_HOME=C:\Program Files\Java\AspectJ
echo Building annotation processor
cd "%SRC_PATH%\SO_AJ_ITD_AddMainMethodToAllSubclasses_APT"
rmdir /s /q bin
del /q processor.jar
call "%ASPECTJ_HOME%\bin\ajc.bat" -8 -sourceroots src -d bin -cp "c:\Program Files\Java\AspectJ\lib\aspectjrt.jar"
jar -cvf processor.jar -C src META-INF -C bin .
echo.
echo Generating aspects and building project
cd "%SRC_PATH%\SO_AJ_ITD_AddMainMethodToAllSubclasses_AJ"
rmdir /s /q bin .apt_generated
call "%ASPECTJ_HOME%\bin\ajc.bat" -8 -sourceroots src -d bin -s .apt_generated -cp "c:\Program Files\Java\AspectJ\lib\aspectjrt.jar";..\SO_AJ_ITD_AddMainMethodToAllSubclasses_APT\processor.jar
echo.
echo Running de.scrum_master.app.App
java -cp bin;"c:\Program Files\Java\AspectJ\lib\aspectjrt.jar" de.scrum_master.app.App
echo.
echo Running de.scrum_master.app.FooApp
java -cp bin;"c:\Program Files\Java\AspectJ\lib\aspectjrt.jar" de.scrum_master.app.FooApp
echo.
echo Running de.scrum_master.app.BarApp
java -cp bin;"c:\Program Files\Java\AspectJ\lib\aspectjrt.jar" de.scrum_master.app.BarApp
Console output: If you run the batch file, the output should look as follows:
Building annotation processor
Manifest wurde hinzugefügt
Eintrag META-INF/ wird ignoriert
META-INF/services/ wird hinzugefügt(ein = 0) (aus = 0)(0 % gespeichert)
META-INF/services/javax.annotation.processing.Processor wird hinzugefügt(ein = 43) (aus = 45)(-4 % verkleinert)
de/ wird hinzugefügt(ein = 0) (aus = 0)(0 % gespeichert)
de/scrum_master/ wird hinzugefügt(ein = 0) (aus = 0)(0 % gespeichert)
de/scrum_master/app/ wird hinzugefügt(ein = 0) (aus = 0)(0 % gespeichert)
de/scrum_master/app/EntryPoint.class wird hinzugefügt(ein = 430) (aus = 253)(41 % verkleinert)
de/scrum_master/aspect/ wird hinzugefügt(ein = 0) (aus = 0)(0 % gespeichert)
de/scrum_master/aspect/EntryPointProcessor.class wird hinzugefügt(ein = 5782) (aus = 2617)(54 % verkleinert)
Generating aspects and building project
Generated aspect de.scrum_master.app.MainMethodAspect_App to advise de.scrum_master.app.App
Generated aspect de.scrum_master.app.MainMethodAspect_BarApp to advise de.scrum_master.app.BarApp
Generated aspect de.scrum_master.app.MainMethodAspect_FooApp to advise de.scrum_master.app.FooApp
Running de.scrum_master.app.App
Doing something
Running de.scrum_master.app.FooApp
Doing something
Doing foo
Running de.scrum_master.app.BarApp
Doing something
Doing bar
If you look at the files generated by the annotation processor under SO_AJ_ITD_AddMainMethodToAllSubclasses_AJ\.apt_generated, you will find three classes looking like this (I am showing just one of them as a sample):
package de.scrum_master.app;
public aspect MainMethodAspect_FooApp {
public static void FooApp.main(String[] args) {
FooApp fooApp = new FooApp();
fooApp.doSomething();
fooApp.doFoo();
}
}
Sorry for this lenghty answer, but other than creating a GitHub repo and just pointing there, I had to mention it all in order to make it reproducible.
Enjoy!

how do I manipulate JList with JList?

I have two JLists, the other has categories of weapons (I'm doing roleplaying character creation software) and the other has items in that specific category. I want the items to change according to category
At the moment jList with items swaps its DefaultListModel every time user changes category (every DefaultListModel variable has different sets of items) this somehow produces NullPointerException whenever user clicks an Item after changing category.
I've tried to search this online and I have read the examples with JList's, but I haven't been able to solve the problem.
Here is the related code
private void jList1ValueChanged(javax.swing.event.ListSelectionEvent evt) { //Kategory
String selection = jList1.getSelectedValue().toString();
if(selection.equals(settings.weapon_classes[0])){
jList2.clearSelection();
jList2.setModel(model_l_pistols);
jList2.validate();
}
if(selection.equals(settings.weapon_classes[1])){
jList2.clearSelection();
jList2.setModel(model_m_pistols);
jList2.validate();
}
}
private void wpn_available_valuechanged_listener(javax.swing.event.ListSelectionEvent evt) {
Weapon wpn = new Weapon(); //The details of selected weapon are stored here for desplaying
try{
String wpn_name = jList2.getSelectedValue().toString();
if(jList1.getSelectedValue().equals("Light pistols")){
wpn = controller.get_Weapon(wpn_name, settings.light_pistols); //Stores right item details from array in settings class
}
if(jList1.getSelectedValue().equals("Medium pistols")){
wpn = controller.get_Weapon(wpn_name, settings.medium_pistols);
}
}catch(Exception e){
System.out.println(e + "String wpn_name = jList2.getSelectedValue().toString();");
}
}
And here is the errormessage I get when running my program with NetBeans IDE (first line includes my try/catch block printing of exception:
java.lang.NullPointerExceptionString wpn_name = jList2.getSelectedValue().toString();
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at charcreation.GUI.wpn_available_valuechanged_listener(Unknown Source)
at charcreation.GUI.access$6900(Unknown Source)
at charcreation.GUI$67.valueChanged(Unknown Source)
at javax.swing.JList.fireSelectionValueChanged(JList.java:1765)
at javax.swing.JList$ListSelectionHandler.valueChanged(JList.java:1779)
at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:167)
at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:147)
at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:194)
at javax.swing.DefaultListSelectionModel.changeSelection(DefaultListSelectionModel.java:388)
at javax.swing.DefaultListSelectionModel.changeSelection(DefaultListSelectionModel.java:398)
at javax.swing.DefaultListSelectionModel.removeSelectionIntervalImpl(DefaultListSelectionModel.java:559)
at javax.swing.DefaultListSelectionModel.clearSelection(DefaultListSelectionModel.java:403)
at javax.swing.JList.clearSelection(JList.java:2013)
at charcreation.GUI.jList1ValueChanged(Unknown Source)
at charcreation.GUI.access$6800(Unknown Source)
at charcreation.GUI$66.valueChanged(Unknown Source)
at javax.swing.JList.fireSelectionValueChanged(JList.java:1765)
at javax.swing.JList$ListSelectionHandler.valueChanged(JList.java:1779)
at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:167)
at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:147)
at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:194)
at javax.swing.DefaultListSelectionModel.changeSelection(DefaultListSelectionModel.java:388)
at javax.swing.DefaultListSelectionModel.changeSelection(DefaultListSelectionModel.java:398)
at javax.swing.DefaultListSelectionModel.setSelectionInterval(DefaultListSelectionModel.java:442)
at javax.swing.JList.setSelectionInterval(JList.java:2035)
at javax.swing.plaf.basic.BasicListUI$Handler.adjustSelection(BasicListUI.java:2731)
at javax.swing.plaf.basic.BasicListUI$Handler.mousePressed(BasicListUI.java:2687)
at java.awt.AWTEventMulticaster.mousePressed(AWTEventMulticaster.java:263)
at java.awt.Component.processMouseEvent(Component.java:6260)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
at java.awt.Component.processEvent(Component.java:6028)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Component.dispatchEventImpl(Component.java:4630)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4460)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4574)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4235)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
at java.awt.Container.dispatchEventImpl(Container.java:2085)
at java.awt.Window.dispatchEventImpl(Window.java:2475)
at java.awt.Component.dispatchEvent(Component.java:4460)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
Possible error could be in this line
String selection = jList1.getSelectedValue().toString();
jList1.getSelectedValue() can be a null value so when the toString() function calls against a null it throws an exception
Use this instead to avoid the exception
String selection = String.valueOf(jList1.getSelectedValue());
This way if it is a null selection you will just get back the String value of null;