Parallel execution with Jbehave with pico (jbehave-pico) - jbehave

I'm new Jbehave. Im trying to find a way to achieve world in cucumber with Jbehave.
I generated project with jbehave with pico archetype. Im trying to run two stories in parallel. I updated threads in pom.xml to 2.
Consider a sample stepdef class as below
public class PojoSteps {
public Pojo pojo;
public PojoSteps(Pojo pojo){
this.pojo = pojo;
System.out.println(" ##" + new Timestamp(System.currentTimeMillis()) + " * this is " + this + ". In PojoSteps constructor. Pojo created is:" + this.pojo + ". Thread = " + Thread.currentThread().getId());
}
#Given("I have a pojo with $i")
public void iHaveAPojoWith1(int i){
pojo.setI(i);
System.out.println(" ##" + new Timestamp(System.currentTimeMillis()) + " * this is " + this + ".In iHaveAPojoWith1. pojo = " + this.pojo +". Value of To be set = " + i +". Value set Pojo.getI() = " + this.pojo.getI() + ". Thread = " + Thread.currentThread().getId());
}
#When("I wait for some time")
public void randomWait() throws InterruptedException {
Thread.sleep(new Random().nextInt(200));
}
#Then("my pojo should still have $expectedi")
public void myPojoShouldStillHave1(int expectedi){
System.out.println(" ##" + new Timestamp(System.currentTimeMillis()) + " * this is " + this +". In myPojoShouldStillHave1. pojo = " + this.pojo + ". expected = " + expectedi + ". actual = " + this.pojo.getI() + ". Thread = " + Thread.currentThread().getId());
Assert.assertEquals(this.pojo.getI(), expectedi);
}
}
I have Pojo model as below
public class Pojo {
private int i;
public void setI(int i){
this.i = i;
}
public int getI(){
return this.i;
}
}
My two stories are as below
PojoOne.story
Scenario: scenario description
Given I have a pojo with 1
When I wait for some time
Then my pojo should still have 1
PojoTwo.story
Scenario: random description
Given I have a pojo with 2
When I wait for some time
Then my pojo should still have 2
I have MyStories class which extends JUnitStories as below
public class MyStories extends JUnitStories {
....
private PicoContainer createPicoContainer() {
MutablePicoContainer container = new DefaultPicoContainer(new Caching().wrap(new ConstructorInjection()));
container.addComponent(PojoSteps.class);
container.addComponent(Pojo.class);
return container;
}
}
When I don't run stories in parallel, they succeed. When I run stories in parallel, they are failing.
##2020-01-02 20:35:36.53 * this is learning.steps.PojoSteps#49f3f232. In PojoSteps constructor. Pojo created is:learning.Support.Pojo#4aa9e824. Thread = 12
##2020-01-02 20:35:36.531 * this is learning.steps.PojoSteps#49f3f232.In iHaveAPojoWith1. pojo = learning.Support.Pojo#4aa9e824. Value of To be set = 1. Value set Pojo.getI() = 1. Thread = 12
##2020-01-02 20:35:36.532 * this is learning.steps.PojoSteps#6136e035. In PojoSteps constructor. Pojo created is:learning.Support.Pojo#1f4412c8. Thread = 13
##2020-01-02 20:35:36.533 * this is learning.steps.PojoSteps#6136e035.In iHaveAPojoWith1. pojo = learning.Support.Pojo#1f4412c8. Value of To be set = 2. Value set Pojo.getI() = 2. Thread = 13
##2020-01-02 20:35:36.558 * this is learning.steps.PojoSteps#6136e035. In myPojoShouldStillHave1. pojo = learning.Support.Pojo#1f4412c8. expected = 1. actual = 2. Thread = 12
##2020-01-02 20:35:36.668 * this is learning.steps.PojoSteps#6136e035. In myPojoShouldStillHave1. pojo = learning.Support.Pojo#1f4412c8. expected = 2. actual = 2. Thread = 13
...
Then my pojo should still have 1 (FAILED)
(java.lang.AssertionError: expected:<2> but was:<1>)
I'm not able to find documentation on how to run tests in parallel with Jbehave and pico. Also I need to have a model outside my stepdef class as I will be having multiple stefdef classes which will share the same model instance.

After reading a bit more and trying out Jbehave with spring,
1. I think there is no way to get different instances of stepdef created per thread.
2. In Jbehave, there is no equivalent of cucumber's world object which is threadsafe.
As #VaL mentioned in the comments of the questions, we have to make thinks threadsafe explicitly.
This is my understanding as of now. If there is any better way - kindly let me know.

Related

Flutter - How to use data from equal built classes?

I want to build an app for my pupil which generates tasks out of sentence blocks.
For example I created two classes, apple and pear, with nearly the same structure. They return a question built out of the sentence blocks which are defined in the classes. In both classes is a GenerateQuestion()-function for that.
Now I want to build some kind of overclass, which picks a random class of i.e. apple or pear and then returns the strings from the functions. The functions names are the same, but I can't figure out how to get data from a random choosen class. Hoping for help. Thanks in advance.
Update: Here is the code I wrote so far (I tried to translate it properly):
import 'dart:math';
int randomminmax1 = 0;
int randomminmax2 = 0;
int randomminmax3 = 0;
List classes = [apple, pear];
class overClass {
static pickClass(){
int randomClassItem = Random().nextInt(classes.length);
print(classes[randomClassItem]);
return classes[randomClassItem];
}
}
class apple {
static String giveQuestion() {
randomminmax1 = 2 + Random().nextInt(15 - 2);
randomminmax2 = randomminmax1 * (2+Random().nextInt(12 - 2));
randomminmax3 = 2 + Random().nextInt(30 - 2);
List value_1 = [" boxes", " bags", " bucket"];
List verbs = ["cost","have a price of", "are offered for"];
List value_2 = ["Euro"];
List questionWords = [""];
int randomIndexValue1 = Random().nextInt(value_1.length);
int randomIndexVerbs = Random().nextInt(verbs.length);
int randomIndexValue2 = Random().nextInt(value_2.length);
String value = randomminmax1.toString() + value_1[randomIndexValue1].toString() + " apples" + verbs[randomIndexVerbs].toString() + " " + randomminmax2.toString() + " " + value_2[randomIndexValue2].toString() + ".\n";
String question = "How much are " + randomminmax3.toString() + value_1[randomIndexValue1].toString() + "?\n";
return value + question;
}
static String giveAnswer(){
double result = (randomminmax2/randomminmax1)*randomminmax3;
return result.toStringAsFixed(2) + " Euro.";
}
}
class pear {
static String giveQuestion() {
randomminmax1 = 2 + Random().nextInt(15 - 2);
randomminmax2 = randomminmax1 * (2+Random().nextInt(12 - 2));
randomminmax3 = 2 + Random().nextInt(30 - 2);
List value_1 = [" boxes", " bags", " bucket"];
List verbs = ["cost","have a price of", "are offered for"];
List value_2 = ["Euro"];
List questionWords = [""];
int randomIndexValue1 = Random().nextInt(value_1.length);
int randomIndexVerbs = Random().nextInt(verbs.length);
int randomIndexValue2 = Random().nextInt(value_2.length);
String value = randomminmax1.toString() + value_1[randomIndexValue1].toString() + " pears" + verbs[randomIndexVerbs].toString() + " " + randomminmax2.toString() + " " + value_2[randomIndexValue2].toString() + ".\n";
String question = "How much are " + randomminmax3.toString() + value_1[randomIndexValue1].toString() + "?\n";
return value + question;
}
static String giveAnswer(){
double result = (randomminmax2/randomminmax1)*randomminmax3;
return result.toStringAsFixed(2) + " Euro.";
}
}
static String giveAnswer(){
double result = (randomminmax2/randomminmax1)*randomminmax3;
return result.toStringAsFixed(2) + " Euro.";
}
}
Can you try to create a superclass that all question classes will inherit and then get the subclasses and programmatically call functions. Try to see here
At least I managed to give my values directly from the classes into the list. But then I got problems with the int-variables, which were built wrong.
My "solution": I converted my classes into isolated flutter widgets, which works fine, except the problem that I'm not able to put the widgets into a list, from where they are picked randomly...but therefore I'll write a new post.
Thank you Moustapha for your help (the superclass idea sounds good, but way too hard to code for me) ;)!

Bukkit - Displaying null when getting a string from the config file

So I've been working on a custom feature for my minecraft server, one of the things that I need to do is get an integer from the config file that is specific to each player to display how many Packages(keys) they have (Virtual items)
The issue that I am having is that in the GUI it is displaying 'null' instead of how many they have... Could anyone help me please?
Item in the gui
Code for creating the player's instance in the config (Using a custom file class that was provided to me by a friend of mine.)
#EventHandler
public void playerJoin(PlayerJoinEvent event) {
Main main = Main.getPlugin(Main.class);
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
if (!main.getDataFolder().exists())
main.getDataFolder().mkdirs();
File file = new File(main.getDataFolder(), "players.yml");
FileConfiguration config = YamlConfiguration.loadConfiguration(file);
if (!config.contains("Users." + uuid + ".Username")) {
try {
System.out.println("Creating entry for " + player + " (" + uuid + ")");
config.set("Users." + uuid + ".Username", player);
config.set("Users." + uuid + ".Packages.Common", 0);
config.set("Users." + uuid + ".Packages.Rare", 0);
config.set("Users." + uuid + ".Packages.Epic", 0);
config.set("Users." + uuid + ".Packages.Legendary", 0);
config.set("Users." + uuid + ".Packages.Exotic", 0);
config.save(file);
System.out.println("Successfully created the entry for " + " (" + uuid + ")");
} catch (Exception e) {
}
}
}
Code for the creation of the item in the gui:
public static String inventoryname = Utils.chat("&fWhite Backpack");
public static Inventory WhiteBackpack(Player player) {
UUID uuid = player.getUniqueId();
Inventory inv = Bukkit.createInventory(null, 27, (inventoryname));
ItemStack common = new ItemStack(Material.INK_SACK);
common.setDurability((byte) 8);
ItemMeta commonMeta = common.getItemMeta();
commonMeta.setDisplayName(Utils.chat("&fCommon Packages &8» &f&l" + Main.pl.getFileControl().getConfig().getString("Users." + uuid + ".Packages.Common")));
common.setItemMeta(commonMeta);
inv.setItem(10, common);
return inv;
}
There are a couple things wrong with your code.
First, you never account for what happens if the config you are loading does not exist. When you do main.getDataFolder().mkdirs(), you account for if the folder is missing, but not the file.
Second, you are doing the following operation:
config.set("Users." + uuid + ".Username", player);
This is incorrect because the player variable is of the type Player, not of the type String. To fix this, you need to instead do the following:
config.set("Users." + uuid + ".Username", player.getName());
Third, you are attempting to write to a file that might not exist. When you initialize you file, you need to also make sure it exists, and if it does not, you need to create it. Right now you have the following:
File file = new File(main.getDataFolder(), "players.yml");
It must be changed to this block of code:
File file = new File(main.getDataFolder(), "players.yml");
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException ex) {
ex.printStackTrace();
}
}
You could just have it be created when you attempt to save the file later on, but that is not ideal since it's safer to let Bukkit write to a file that already exists.
Fourth, and I'm not necessarily sure that this is a problem per se, but you are trying to access an Integer value from the config file as if it were a String. Try to replace the following:
commonMeta.setDisplayName(Utils.chat("&fCommon Packages &8» &f&l"
+ Main.pl.getFileControl().getConfig().getString("Users." + uuid + ".Packages.Common")));
with this instead:
commonMeta.setDisplayName(Utils.chat("&fCommon Packages &8» &f&l"
+ Main.pl.getFileControl().getConfig().getInt("Users." + uuid + ".Packages.Common")));
Hope this gets you moving in the right direction!

Manipulate Date/Time in RDF4J for Debugging

I'm using RDF4J 2.2.1 on Windows 10 Professional 64-bit. I will have some SPIN constructor rules which are sensitive to date/time. For example, I may want to compare a triple containing an xsd:dateTime datatype property to the output of SPARQL's built-in now() function. To debug this functionality, it would be convenient to manipulate RDF4J's perception of date/time somehow rather than manipulating the system clock. I'm aware that there is general commercial software (e.g. Solution Soft's "Time Machine") that can generally manipulate the perception of time for any Windows process. However, this software appears to be far too expensive for our little proof-of-concept project.
What I'd like to be able to do:
Set RDF4J's date/time to some arbitrary date/time value.
Have RDF4J's date/time proceed at real time speed or at some programmable faster speed during debugging.
Does anyone have suggestions for how to manipulate in this manner date/time for RDF4J? It would make my debugging of time-sensitive SPIN rules much more efficient. I'd prefer not to fight my PC's system clock since many other things depend on it. I suppose that running an entire virtual PC and debugging on the virtual PC is another option, but it seems there should be a simpler way.
Thanks.
You could accomplish this by implementing a custom SPARQL function and using that instead of the actual now() function. Call it mock_now() for example. Since you implement it, you have full control over its behavior.
I'm posting my solution to my question in hopes it might help others as a further example of a custom SPARQL function under RDF4J. I don't hold this out as en elegant solution (due to how I set test conditions), but it does work and meets my requirements. This solution extends the answer from #jeen_broekstra based on http://docs.rdf4j.org/custom-sparql-functions/...
I now have a custom implemented in the namespace defined by PREFIX soo: <http://www.disa.mil/dso/a2i/ontologies/PBSM/Sharing/SpectrumOperationsOntology#>as a function called soo:spectrumOpsDateTime() which can take either three or no arguments. The three arguments case allows setting the scaled date time as follows.
First argument: xsd:boolean... use system clock if true or use scaled clock if false
Second argument: xsd:dateTime (ignored if first argument is true)... the starting date/time for scaled clock operation
Third argument: xsd:double (ignored if first argument is true)... the scaled clock rate (e.g. 2.0 means the scaled clock runs faster, at twice real time)
If there are no arguments, soo:spectrumOpsDateTime() returns the scaled date/time or the system date/time depending on what the initial values in the Java code specify or what the last three-argument call specified. The SPARQL and SPIN code under test will use only the no-argument version. Test setup queries will set up the time conditions for particular tests.
Here's an example SPARQL setup query to set up a 2x speed starting this morning:
PREFIX soo: <http://www.disa.mil/dso/a2i/ontologies/PBSM/Sharing/SpectrumOperationsOntology#>
SELECT DISTINCT *
WHERE {
BIND(soo:spectrumOpsDateTime("false"^^xsd:boolean, "2017-08-22T10:49:21.019-05:00"^^xsd:dateTime, "2.0"^^xsd:double) AS ?testDateTime) .
}
Here's an example SPARQL query to get the scaled date/time:
PREFIX soo: <http://www.disa.mil/dso/a2i/ontologies/PBSM/Sharing/SpectrumOperationsOntology#>
SELECT DISTINCT *
WHERE {
BIND(soo:spectrumOpsDateTime() AS ?testDateTime) .
}
The single class used to implement this custom function is:
/**
*
*/
package mil.disa.dso.spo.a2i.nsc.sharing2025.scaledDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
import org.eclipse.rdf4j.query.algebra.evaluation.ValueExprEvaluationException;
import org.eclipse.rdf4j.query.algebra.evaluation.function.Function;
/**
* Class for generating a configurable date/time clock that can either be a pass-through of the
* system clock or a scaled clock starting at a specified date/time running at a specified
* rate from that specified time (first call).
* #author Greg Cox of Roberson and Associates &copy Copyright 2017 Roberson and Associates, All Right Reserved
*
*/
public class DateTimeGenerator implements Function {
private static final String thisClassName = "RDF4JCustomSPARQLFunction." + DateTimeGenerator.class.getSimpleName();
private static final String thisClassFullName = DateTimeGenerator.class.getName();
private static final boolean errorMessages = true;
private static final boolean verboseMessages = true;
private double clockPace = 2.0; // the speed of the clock, 1.0 is real time, 2.0 is 2x real time (double speed)
private boolean useSystemClock = false; // flag to indicate whether to use scaled clock or pass through the system clock
private ZonedDateTime startingRealDateTime = null; // the real time stamp at the first call to the evaluate function
private ZonedDateTime startingScaledDateTime = // the scaled time stamp (starting scaled time) at the first call to the evaluate function
ZonedDateTime.parse("2016-08-21T17:29:37.568-05:00");
// define a constant for the namespace of custom function
private static String NAMESPACE = "http://www.disa.mil/dso/a2i/ontologies/PBSM/Sharing/SpectrumOperationsOntology#"; // defined as soo: elsewhere
// this is the evaluate function needed to implement the RDF4J Function interface
// it can take 0 or 3 arguments
// 0 - get the current scaled time (starting by first call)
// 3 - useSystemClock flag (true/false), starting date/time (xsd:dateTime), clock pace (non-negative real w/ 1.0 meaning 1sec = 1sec)
#SuppressWarnings("unused")
#Override
public Value evaluate(ValueFactory valueFactory, Value... args) throws ValueExprEvaluationException {
String thisMethodMessagePrefix = "";
if (errorMessages || verboseMessages ) {
String thisMethodName = ".evaluate: ";
thisMethodMessagePrefix = thisClassName + thisMethodName;
}
if (args.length == 3) {
// Three arguments --> attempting to set mode/parameters, so attempt to parse/check them
if (verboseMessages) System.out.println(thisMethodMessagePrefix + "attempting to set scaled clock mode/parameters");
boolean argErrFlag = false;
boolean newUseSystemClock = false;
String argErrMessage = "";
// first argument should be true/false on whether to use system clock (true) or scaled clock (false)
if (!(args[0] instanceof Literal)) {
argErrFlag = true;
argErrMessage += "first argument must be a literal true/false value... ";
} else {
String useSystemClockString = args[0].stringValue();
if (useSystemClockString.equalsIgnoreCase("true")) {
if (verboseMessages) System.out.println(thisMethodMessagePrefix + "use system clock specified");
newUseSystemClock = true;
} else if (useSystemClockString.equalsIgnoreCase("false")) {
if (verboseMessages) System.out.println(thisMethodMessagePrefix + "use scaled clock specified");
newUseSystemClock = false;
}
else {
argErrFlag = true;
argErrMessage += "first argument must be a literal true/false value... ";
}
}
// second argument should be starting date/time for scaled clock (ignore if using system clock)
ZonedDateTime startTime = null;
if (!newUseSystemClock) {
if (!(args[1] instanceof Literal)) {
argErrFlag = true;
argErrMessage += "second argument must be literal xsd:dateTime value for start of scaled date/time... ";
} else {
String startDateTimeString = args[1].stringValue();
try {
startTime = ZonedDateTime.parse(startDateTimeString);
} catch (Exception e) {
argErrFlag = true;
argErrMessage += "could not parse starting date/time... " + e.getMessage() + "... ";
}
}
}
// third argument should be clock pace for scaled clock (ignore if using system clock)
Double newClockPace = null;
if (!newUseSystemClock) {
if (!(args[2] instanceof Literal)) {
argErrFlag = true;
argErrMessage += "third argument must be literal xsd:double value for clock pace... ";
} else {
String clockPaceString = args[2].stringValue();
try {
newClockPace = Double.parseDouble(clockPaceString);
} catch (Exception e) {
argErrFlag = true;
argErrMessage += "could not parse clock pace which should be a positive xsd:double... ";
}
if ((newClockPace != null) && (newClockPace <= 0.0)) {
argErrFlag = true;
argErrMessage += "clock pace must be positive, got " + newClockPace + "... ";
}
}
}
// check for errors and set up the generator if no errors...
if (argErrFlag) {
if (errorMessages) System.err.println(thisMethodMessagePrefix + "ERROR - " + argErrMessage);
if (errorMessages) System.err.println(thisMethodMessagePrefix + "throwing exception...");
throw new ValueExprEvaluationException(
"spectrum operations time function soo:spectrumOpsDateTime() encountered errors in function arguments... " +
argErrMessage);
} else if (newUseSystemClock) {
if (verboseMessages) System.out.println(thisMethodMessagePrefix + "using unscaled system clock");
useSystemClock = newUseSystemClock;
} else if (!newUseSystemClock) {
if (verboseMessages) System.out.println(thisMethodMessagePrefix + "using scaled time");
useSystemClock = newUseSystemClock;
startingRealDateTime = ZonedDateTime.now();
if (verboseMessages) System.out.println(thisMethodMessagePrefix + "setting starting real time to " + startingRealDateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));
if (verboseMessages) System.out.println(thisMethodMessagePrefix + "setting start time to " + startTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));
startingScaledDateTime = startTime;
if (verboseMessages) System.out.println(thisMethodMessagePrefix + "setting clock pace to " + String.format("%5.2f", newClockPace * 100.0) + "%");
clockPace = newClockPace;
}
} else if (args.length != 0) { // can only have no arguments or three arguments...
throw new ValueExprEvaluationException(
"spectrum operations time function soo:spectrumOpsDateTime() requires "
+ "zero arguments or three arguments, got "
+ args.length + " arguments");
}
// now run the generator and return the result...
IRI xsdDateTimeIRI = valueFactory.createIRI("http://www.w3.org/2001/XMLSchema#dateTime"); // long-form equivalent to xsd:dateTime
if (useSystemClock) {
String unscaledTimeString = millisTrailingZeroes(ZonedDateTime.now().format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));
return valueFactory.createLiteral(unscaledTimeString, xsdDateTimeIRI);
} else {
errString = null;
String scaledTimeString = millisTrailingZeroes(getScaledDateTime().format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));
if (scaledTimeString == null) {
if (errorMessages) System.err.println(thisMethodMessagePrefix + "ERROR - scaled time returned null");
if (errorMessages) System.err.println(thisMethodMessagePrefix + "thowing exception...");
throw new ValueExprEvaluationException("could not generate valid scaled time string" + ((errString == null) ? "" : "... " + errString));
}
return valueFactory.createLiteral(scaledTimeString, xsdDateTimeIRI);
}
}
private static String errString = null;
/**
* Utility method to make all the millisecond fields of an <tt>ISO_OFFSET_DATE_TIME</tt> three digits by
* adding trailing zeroes as needed. Why? Because of trouble with various implementations interpreting
* 1 and 2 digit milliseconds differently. Should be standard decimal, but sometimes interpreted
* as number of milliseconds (e.g. .39T interpreted as 39 millieconds inststead of 390 milliseconds)
* #param <tt>ISO_OFFSET_DATE_TIME</tt> string to check for millisecond field length
* #return <tt>ISO_OFFSET_DATE_TIME</tt> strnig with trailing zeroes in milliseconds field
* as require to make the field three digits or <tt>null</tt> on error
*/
private static String millisTrailingZeroes(String isoDateTimeString) {
if (isoDateTimeString == null) {
errString = "DateTimeGenerator.millisTrailingZeroes: got null isoDateTimeString argument, returning null...";
return null;
}
String[] ss_l1 = isoDateTimeString.split("\\."); // Example: 2017-08-18T13:01:05.39-05:00 --> 2017-08-18T13:01:05 AND 39-05:00
if (ss_l1.length != 2) {
errString = "DateTImeGenerator.millisTrailingZeros: first parsing split of isoDateTimeString=" + isoDateTimeString + " by '.' got unexpected number of parts=" + ss_l1.length;
return null;
}
String[] ss_l2 = ss_l1[1].split("-"); // 39-05:00 --> 39 AND 05:00
if (ss_l2.length != 2) {
errString = "DateTImeGenerator.millisTrailingZeros: second parsing split of " + ss_l1[1] + " by '-' got unexpected number of parts=" + ss_l2.length;
return null;
}
if (ss_l2[0].length() == 1) {
ss_l2[0] = ss_l2[0] + "00";
} else if (ss_l2[0].length() == 2)
ss_l2[0] = ss_l2[0] + "0"; // 39 --> 390
return ss_l1[0] + "." + ss_l2[0] + "-" + ss_l2[1]; // 2017-08-18T13:01:05.390-05:00
}
/**
* Method to get the current scaled date time according to the state of this DateTimeGenerator.
* If <tt>useSystemClock</tt> is <tt>true</tt>, then time is not
* scaled and system time is returned instead of scaled time.
* #return scaled date time if <tt>useSystemClock</tt> is <tt>true</tt> or
* system date time if <tt>useSystemClock</tt> is <tt>false</tt>
*/
private ZonedDateTime getScaledDateTime() {
ZonedDateTime scaledDateTime = null;
if (useSystemClock) {
scaledDateTime = ZonedDateTime.now();
} else {
if (startingRealDateTime == null)
startingRealDateTime = ZonedDateTime.now();
long realMillisFromFirstCall = ChronoUnit.MILLIS.between(startingRealDateTime, ZonedDateTime.now());
long scaledMillisFromFirstCall = (long) ((double) realMillisFromFirstCall * clockPace);
scaledDateTime = ChronoUnit.MILLIS.addTo(startingScaledDateTime, scaledMillisFromFirstCall);
}
return scaledDateTime;
}
#Override
public String getURI() {
return NAMESPACE + "spectrumOpsDateTime";
}
/**
* Test main method
* #param args command line arguments (ignored)
*/
#SuppressWarnings("unused")
public static void main(String[] args) {
String thisMethodMessagePrefix = "";
if (errorMessages || verboseMessages ) {
String thisMethodName = ".main: ";
thisMethodMessagePrefix = thisClassName + thisMethodName;
}
DateTimeGenerator testGen = new DateTimeGenerator();
if (verboseMessages) System.out.println(thisMethodMessagePrefix + "custom SPARQL method URI: " + testGen.getURI());
if (verboseMessages) System.out.println(thisMethodMessagePrefix + "fully-qualified class name: " + thisClassFullName);
ValueFactory testVF = SimpleValueFactory.getInstance();
Value testValues[] = new Value[0];
while (true) {
if (verboseMessages) System.out.println(thisMethodMessagePrefix + "scaled: " + testGen.evaluate(testVF, testValues).stringValue() +
" current real: " + millisTrailingZeroes(ZonedDateTime.now().format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
In my case, the jar file exported from Eclipse executes under my installation of Apache and resides at C:\Apache\apache-tomcat-8.5.15\webapps\rdf4j-server\WEB-INF\lib\ScaledDateTime.jar I restart the Apache server after replacing this jar file when I do mofifications.

Create class at runtime, serilize and de-serilize then cast to Interface froblem

Hi,
I have the following code :
public static object CreateTypedReport(string typeName, string inheritFrom)
{
DirectoryInfo dirInfo;
CSharpCodeProvider c = new CSharpCodeProvider();
CompilerParameters cp = new CompilerParameters();
foreach (Assembly asm in System.AppDomain.CurrentDomain.GetAssemblies())
{
if(!asm.FullName.StartsWith("ReportAssembly, Version=0.0.0.0"))
cp.ReferencedAssemblies.Add(asm.Location);
}
cp.CompilerOptions = "/t:library";
cp.GenerateInMemory = true;
dirInfo = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\MyApp\\ReportAssemblies\\");
if (!dirInfo.Exists)
dirInfo.Create();
cp.OutputAssembly = dirInfo.FullName + typeName + "Assembly";
cp.ReferencedAssemblies.Add(typeof(XtraReport).Assembly.Location);
//cp.OutputAssembly = typeName + "Assembly";
StringBuilder sb = new StringBuilder("");
sb.Append("using System;\n");
sb.Append("using MyNamespace.UI;\n");
sb.Append("namespace TypedReports { \n");
sb.Append("public class " + typeName + " : " + inheritFrom + "{ \n");
sb.Append("} \n");
sb.Append("}\n");
CompilerResults cr = c.CompileAssemblyFromSource(cp, sb.ToString());
if (cr.Errors.Count > 0)
{
MessageBox.Show("ERROR: " + cr.Errors[0].ErrorText, "Error evaluating cs code", MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
return cr.CompiledAssembly.CreateInstance("TypedReports." + typeName);
}
This will create a class based on the typeName and inheritFrom parameters and then finally an object will be created and returned. inheritFrom will point at a class that implements IMyInterface.
It's possible to cast this object to a IMyInterface if it's needed.
When we then serialize and de-serialize this object we will not be able to cast it to IMyInterface anymore?
Why? And how could I solve it?
The problem was in the serialization och deserialization of the object. When this was changed it worked great. The solution is in a third party product so I can´t post it here.

Template to show method name and parameter values in Eclipse

Is there any way to have a template (Java -> Editor -> Templates) in Eclipse that generate something like this
debug("methodName arg1=" + arg1 + " arg2=" + arg2 + " arg3=" + arg3);
When used in a method. For instance:
public void setImage(long rowId, long contactId, String thinggy) {
// invoking the template here, produces this:
debug("setImage rowId=" + rowId + " contactId=" + contactId + " thinggy=" + thinggy);
}
I couldn't find a way to do that with the standard template UI, maybe there exists a plugin to do this kinds of things?
This is a start:
debug("${enclosing_method_arguments}: ", ${enclosing_method_arguments});
which produces the following:
debug("arg1, arg2, arg3: ", arg1, arg2, arg3);
I haven't found a way to separate out each argument. I found this page that ran into the same problem.
For other Eclipse template stuff, look at this question.
I guess it's probably a bit too late to answer this question but maybe my answer will help someone :
System.out.println(String.format("%tH:% %s", java.util.Calendar.getInstance(), "${enclosing_package}.${enclosing_type}.${enclosing_method}(${enclosing_method_arguments})"));
String[] lArgsNames = new String("${enclosing_method_arguments}").split(", ");
Object[] lArgsValues = new Object[] {${enclosing_method_arguments}};
for (int i = 0; i < lArgsValues.length; i++) {
System.out.println("\t" + (lArgsValues[i] != null ? ("(" + lArgsValues[i].getClass().getSimpleName() + ") \"" + lArgsNames[i] + "\" = \"" + lArgsValues[i] + "\"") : "\"" + lArgsNames[i] + "\" is null"));
}
For this method :
public void foo(boolean arg){
// ...
}
the output would be:
18:43:43:076 > any.package.AnyClass.foo(arg)
(Boolean) "arg" = "true"
This code seems to be able to handle any object, primitive type and null value. And yes it's a little bit complicated for the purpose!
I've made small plugin that adds nicely formatted variable:
https://github.com/dernasherbrezon/eclipse-log-param
Eclipse doesnt provide any information about parameter type, so there is no Arrays.toString(...)
or template=
if (aLog.isDebugEnabled()) {
aLog.debug(String.format("${enclosing_method}:${enclosing_method_arguments}".replaceAll(", ", "=%s, ")+"=%s", ${enclosing_method_arguments}));
}
gives
public static void hesteFras(boolean connect, Object ged, String frans, int cykel) {
if (aLog.isDebugEnabled()) {
aLog.debug(String.format("hesteFras: connect, ged, frans, cykel".replaceAll(", ", "=%s, ") + "=%s",
connect, ged, frans, cykel));
}
which for
hesteFras(false, null, "sur", 89);
gives a log statement:
hesteFras: connect=false, ged=null, frans=sur, cykel=89
The eclipse-log-param plugin is useful to avoid having to type the logging line manually. However, it would be even nicer to have the line added automatically for all new methods.
Is this even possible? It looks like in Windows->Preferences->Code Style->Code Templates->Code there are ways to configure automatically added code like auto-generated methods ("Method body" template, which has an "Auto-generated method stub" comment). But there's no way to configure new methods which are not generated.
Furthermore, the variable formatted_method_parameters is not available when editing the template for "Method body".