I want to create a construct that would work with pageable feign api calls and dry them from the first page of declared size available to the last one.
To take in account:
the feign method calls can differ in arg. count tho last two is always page and it's size
data structure returned is similar to the extent of paging information, but core data list received type differs
This is what I did:
method that is a base for draining a particular api call:
public <T> List<BaseFeignResult<T>> drainFeignPageableCall(
PagedCall<T> feignCall
) {
BaseFeignResult<T> firstPage = feignCall.call(0, 10);
List<BaseFeignResult<T>> baseFeignResults = drainFeignPageableCall(feignCall, firstPage, Lists.newArrayList(firstPage), 1);
return baseFeignResults;
}
It's overload and continuation:
<T> List<BaseFeignResult<T>> drainFeignPageableCall(
PagedCall<T> feignCall,
BaseFeignResult<T> dataPage,
List<BaseFeignResult<T>> acc,
int page
) {
if (dataPage.resp.getBody().getData().size() % 10 > 0)
return acc;
BaseFeignResult<T> res = feignCall.call(page, 10);
acc.add(res);
return drainFeignPageableCall(feignCall, res, acc, ++page);
}
And the definitions:
public static class SingleParamPageableCall<T> implements PagedCall<T> {
SingleParamPagingApi<T> fun;
String param;
public SingleParamPageableCall(SingleParamPagingApi<T> fun, String param) {
this.fun = fun;
this.param = param;
}
#Override
public BaseFeignResult<T> call(int p, int s) {
BaseFeignResult.BaseFeignResultBuilder<T> builder = BaseFeignResult.builder();
try {
builder.resp(fun.callFeignApi(param, p, s));
} catch (RuntimeException e) {
builder.excp(e);
}
return builder.build();
}
}
public interface PagedCall<T> {
BaseFeignResult<T> call(int p, int s);
}
#Builder
public static class BaseFeignResult<T> {
private final ResponseEntity<IVDPagedResponseOf<T>> resp;
private final RuntimeException excp;
}
public interface SingleParamPagingApi<T> {
ResponseEntity<IVDPagedResponseOf<T>> callFeignApi(String arg, int page, int size) throws RuntimeException;
}
This can be arbitraliry called as:
drainFeignPageableCall(new BaseService.SingleParamPageableCall<GetOrderInfoDto>(ordersFeignClient::getOrdersBySampleIds, "34596"));
and works as expected.
So as you can see, if I want to keep some sort of abstraction above various drain-able per api calls, I need to introduce definitions like SingleParamPagingApi and class implementation of SingleParamPageableCall<T>. so with every other api to be treated this way, I would need to redefine those.
My question here is: how to do this in purely descripive way, or how to reimplement this as a functional programming?
to be clear: I would like to have code impl. in which I would describe how to map parameters to the method call (that can and will vary) and return a common data structure with the data being of generic type.
Basically I am looking for the most descriptive way of re-implementing this in Java without defining heavy objects like SingleParamPagingApi<T>, but describing how to mount params called with to API params itself rather.
Thank you!
This simplest way would be to replace your SingleParamPagingApi interface with one that has a method that just takes the page no and size as parameters (PagingApi). And replace SingleParamPageableCall with a class that just takes a PagingApi argument. Then you can create the variants of PagingApi for 1 parameter, 2 parameters etc by immediately binding the method to the argument 0, argument 1 etc, thereby creating a PagingApi instance (the of methods).
public interface PagingApi1<T, A0> {
ResponseEntity<IVDPagedResponseOf<T>> callFeignApi(A0 arg0, int page, int size) throws RuntimeException;
}
public interface PagingApi2<T, A0, A1> {
ResponseEntity<IVDPagedResponseOf<T>> callFeignApi(A0 arg0, A1 arg1, int page, int size) throws RuntimeException;
}
public interface PagingApi<T> {
static <T, A0> PagingApi<T> of(PagingApi1<T, A0> api, A0 arg0) {
return (p, s) -> api.callFeignApi(arg0, p, s);
}
static <T, A0, A1> PagingApi<T> of(PagingApi2<T, A0, A1> api, A0 arg0, A1 arg1,) {
return (p, s) -> api.callFeignApi(arg0, arg1, p, s);
}
ResponseEntity<IVDPagedResponseOf<T>> callFeignApi(int page, int size) throws RuntimeException;
}
public static class PageableCall<T> implements PagedCall<T> {
PagingApi<T> fun;
public PageableCall(PagingApi<T> fun) {
this.fun = fun;
}
#Override
public BaseFeignResult<T> call(int p, int s) {
BaseFeignResult.BaseFeignResultBuilder<T> builder = BaseFeignResult.builder();
try {
builder.resp(fun.callFeignApi(p, s));
} catch (RuntimeException e) {
builder.excp(e);
}
return builder.build();
}
}
You would call it as follows:
drainFeignPageableCall(
new PageableCall<GetOrderInfoDto>(
PagingApi.of(ordersFeignClient::getOrdersBySampleIds, "34596")
)
);
As a further simplifcation, you could probably collapse PagingApi and PagedCall into a single interface.
I would also suggest replacing the recursive calls in drainFeignPageableCall with a simple for loop. You might think recursion is more "functional" but it's needlessly complex and inefficient here.
Related
My goal is to use the Either class alongside my Human, Weapon, and Magazine classes.
These are the different Human declarations I want to test. (No weapon, no mag, and has all)
Human noWeapon = new Human(null);
Human noMag = new Human(new Weapon(null));
Human hasAll = new Human(new Weapon(new Magazine(2)));
Currently, I'm creating an Either in the following way:
Human noWeapon = new Human(null);
Either <String, Human> either2 = new Right <String, Human>(noWeapon);
Right <String, Human> either2_right = (Right<String, Human>) either2;
I'm struggling to understand the inner workings of the Either class and the ways for which I can use it for error handling. I want to be able to catch these errors when they occur so I can know when the error is happening
either2_right.getRight().getWeapon().getMag().getCount();
Currently, this is throwing a NullPointerException error for obvious reasons - but my goal is to instead catch the error and know when it occured.
My Either class is as follows:
abstract class Either<A, B> { }
class Left<A, B> extends Either<A, B> {
public A left_value;
public Left(A a)
{
left_value = a;
}
public A getLeft(){
return this.left_value;
}
public <B2> Either<A,B2> flatMap(final Function<B,Either<A,B2>> f){
return (Either<A,B2>)this;
}
public <B2> Either<A,B2> map(final Function<B,B2> f){
return (Either<A,B2>)this;
}
}
class Right<A, B> extends Either<A, B> {
public B right_value;
public Right(B b)
{
right_value = b;
}
public B getRight(){
return this.right_value;
}
public <B2> Either<A,B2> flatMap(final Function<B,Either<A,B2>> f){
return f.apply(right_value);
}
public <B2> Either<A,B2> map(final Function<B,B2> f){
return new Right(f.apply(right_value));
}
}
I'm using Either for my following 3 classes:
Human
class Human {
Weapon w;
public Human(Weapon w)
{
this.w = w;
}
public Weapon getWeapon()
{
return w;
}
}
Weapon:
class Weapon {
Magazine m;
public Weapon(Magazine m)
{
this.m = m;
}
public Magazine getMag()
{
return m;
}
}
Magazine:
class Magazine {
private int count;
public Magazine(int c)
{
count = c;
}
public int getCount()
{
return count;
}
}
Thank you for any help I'm able to get!
I'm struggling to understand the inner workings of the Either class and the ways for which I can use it for error handling.
Let us start with the second part of the question, how can I use Either for error handling?
Either can hold one of two values, for error handling you can declare a method to return an Either that will hold a valid computation result or an Exception. For example:
public Either<ArithmeticException, Double> divide (Double x, Double y) {
try {
return new Right<ArithmeticException, Double>(x/y);
} catch (ArithmeticException e) {
return new Left<ArithmeticException, Double>(e);
}
}
The caller will not get an ArithmeticException if he try to divide by zero, he will receive an Either holding the exception, in this example he will get a Left. The convention is to hold valid return results in a Right and the other results in a Left.
The implementation you provided doesn't make it easy for the caller to check if he got a Right or a Left or make it easy to process the result regardless of it is a Right or a 'Left a more complete implementation of Either here provides that convenience (for instance getOrThrow to get a Right value or throw an exception if the Either is not a Right).
private static Iterable<Object> iterable(
final Object first, final Object second, final Object[] rest) {
checkNotNull(rest);
return new AbstractList<Object>() {
#Override
public int size() {
return rest.length + 2;
}
#Override
public Object get(int index) {
switch (index) {
case 0:
return first;
case 1:
return second;
default:
return rest[index - 2];
}
}
};
}
What is author's purpose?
I guess he wants to make use of the array generated by compiler, rather than new an ArrayList.
But still a confusing point, why not write as below?
private static Iterable<Object> iterable(final Object[] rest) {
checkNotNull(rest);
return new AbstractList<Object>() {
#Override
public int size() {
return rest.length;
}
#Override
public Object get(int index) {
return rest[index];
}
};
}
The point here is that this method is called from public methods which look like (source):
public final String join(
#NullableDecl Object first, #NullableDecl Object second, Object... rest) {
return join(iterable(first, second, rest));
}
Using signatures like this is a trick to force you to pass in at least two arguments - after all, if you've not got two arguments, there is nothing to join.
For example:
Joiner.on(':').join(); // Compiler error.
Joiner.on(':').join("A"); // Compiler error.
Joiner.on(':').join("A", "B"); // OK.
Joiner.on(':').join("A", "B", "C"); // OK.
// etc.
This iterable method just creates an Iterable without having to copy everything into a new array. Doing so would be O(n) in the number of arguments; the approach taken here is O(1).
I am attempting to use JNA to invoke the QueryContextAttributes function in the Secur32.dll on Windows. I am unable to get the invocation correct for the SECPKG_ATTR_SIZES call. I have an implementation working for SECPKG_ATTR_NAMES and SECPKG_ATTR_PACKAGE_INFO. Therefore, I presume (famous last words) the issue is in the definition of the structure, or something about the invocation.
The Microsoft function definition for QueryContextAttributes is:
SECURITY_STATUS SEC_Entry QueryContextAttributes(
_In_ PCtxtHandle phContext,
_In_ ULONG ulAttribute,
_Out_ PVOID pBuffer
);
The Microsoft structure definition for the SecPkgContext_Sizes is:
typedef struct _SecPkgContext_Sizes {
ULONG cbMaxToken;
ULONG cbMaxSignature;
ULONG cbBlockSize;
ULONG cbSecurityTrailer;
} SecPkgContext_Sizes, *PSecPkgContext_Sizes;
The JNA library (I'm using jna-4.2.2 and jna-platform-4.2.2) provides an implementation in the Secur32 for some of the functions in that .dll. The definitions for the structures are at:
SecPkgContext_Names structure,
SecPkgInfo structure, and
SecPkgContext_Sizes structure
I therefore have defined the following:
public interface ISecur32 extends Secur32 {
// get own copy of the INSTANCE variable
ISecur32 INSTANCE = (ISecur32) Native.loadLibrary("Secur32",
ISecur32.class,
W32APIOptions.UNICODE_OPTIONS);
// method definition to match
public int QueryContextAttributes(CtxtHandle phContext,
int SECPKG_ATTR,
PointerByReference pp);
//
// for the SECPKG_ATTR_NAMES call
// NOTE: this definition and invocation is working
//
public static class SecPkgContext_Names extends Structure {
public Pointer pName;
public SecPkgContext_Names(Pointer p)
{ super(p); }
#Override
protected List<?> getFieldOrder()
{ return Arrays.asList(new String[] { "pName" }); }
}
//
// for the SECPKG_ATTR_SIZES call
// NOTE: This invocation is NOT working
//
public static class SecPkgContext_SizesBis extends Structure {
public NativeLong cbMaxToken;
public NativeLong cbMaxSignature;
public NativeLong cbBlockSize;
public NativeLong cbSecurityTrailer;
public SecPkgContext_SizesBis(Pointer p)
{ super(p); }
#Override
protected List<?> getFieldOrder() {
return Arrays.asList(new String[] { "cbMaxToken", "cbMaxSignature",
"cbBlockSize", "cbSecurityTrailer"});
}
} //interface
The call for the Names (which is working) is:
public static void querySecPkgAttr_Names(CtxtHandle phContext) {
final int SECPKG_ATTR_NAMES = 1;
PointerByReference pp = new PointerByReference();
int rc = ISecur32.INSTANCE.QueryContextAttributes(phContext,
SECPKG_ATTR_NAMES,
pp);
if (rc != 0) {
_log.error("Error in QueryContextAttributes: {}", rc);
return;
}
Pointer p = pp.getPointer();
ISecur32.SecPkgContext_Names names = new ISecur32.SecPkgContext_Names(p);
names.read();
String name = names.pName.getWideString(0);
rc = ISecur32.INSTANCE.FreeContextBuffer(p);
_log.debug("FreeContextBuffer: {}", rc);
}
When I attempt to obtain the Sizes (specifically, I'm after the cbMaxSignature value), I use the following call:
public static int querySecPkgAttr_Sizes(CtxtHandle phContext) {
final int SECPKG_ATTR_SIZES = 0; // SECPKG_ATTR_SIZES is 0
PointerByReference pp = new PointerByReference();
int res = ISecur32.INSTANCE.QueryContextAttributes(phContext,
SECPKG_ATTR_SIZES,
pp);
// NOTE: the call is succeeding, so this line is not invoked
if (res != 0) {
return new NativeLong(0);
}
// NOTE: I have also used pp.getPointer()
Pointer p = pp.getValue();
ISecur32.SecPkgContext_Sizes sizes =
new ISecur32.SecPkgContext_Sizes(p);
// THIS LINE THROWS THE Invalid Memory Access Error
sizes.read();
NativeLong maxSig = sizes.cbMaxSignature;
rc = ISecur32.INSTANCE.FreeContextBuffer(p);
_log.debug("FreeContextBuffer: {}", rc);
return maxSig.intValue();
}
Using the above call, I receive the Exception stack trace of:
Exception in thread "main" java.lang.Error: Invalid memory access
at com.sun.jna.Native.getInt(Native Method)
at com.sun.jna.Pointer.getInt(Pointer.java:601)
at com.sun.jna.Pointer.getValue(Pointer.java:389)
at com.sun.jna.Structure.readField(Structure.java:705)
at com.sun.jna.Structure.read(Structure.java:565)
at gov.sandia.dart.sspi.Utils.querySecPkgAttr_Sizes(Utils.java:145)
If instead of the pp.getValue() call, I use pp.getPointer(), I receive (when trying to instantiate the Object, I believe):
java.lang.IllegalArgumentException: Structure exceeds provided memory bounds
I am at a loss as to how to solve this issue.
I apologize for not having a complete program, but to get to the point of having the CtxtHandle needed requires a romp through AcquireCredentialsHandle and InitializeSecurityContext. I believe these are working appropriately, as the Kerberos ticket is showing in the MSLSA cache (viewable via klist) after the InitializeSecurityContext completes.
I also looked at the solution Waffle, but it does not set the correct flags for in the initialization loop, and also does not implement QueryContextAttributes, or the ultimate goal in all of this the MakeSignature function.
I apologize for the length of the post. If I have omitted any piece of information, please let me know.
Thank you!
I was able to resolve the issue I was having, though not in a very elegant manner. Rather than attempting to use the a PointerByReference in the QueryContextAttributes as suggested in the question, I ended up creating multiple method definitions, one for each structure. So I have in the Interface, the approach of:
public int QueryContextAttributes(CtxtHandle phContext,
int SECPKG_ATTR,
SecPkgContext_NegotiationInfo negoInfo);
public static class SecPkgContext_NegotiationInfo extends Structure
{
public Pointer pPackageInfo;
public int negotiationState;
public SecPkgContext_NegotiationInfo() {
super();
}
public SecPkgContext_NegotiationInfo(Pointer p) {
super(p);
}
#Override
protected List<?> getFieldOrder() {
return Arrays.asList(new String[] { "pPackageInfo", "negotiationState"
});
}
}
public int QueryContextAttributes(CtxtHandle phContext,
int SECPKG_ATTR,
SecPkgContext_Sizes sizes);
public static class SecPkgContext_Sizes extends Structure
{
public int cbMaxToken;
public int cbMaxSignature;
public int cbBlockSize;
public int cbSecurityTrailer;
public SecPkgContext_Sizes() {
super();
}
public SecPkgContext_Sizes(Pointer p) {
super(p);
}
#Override
protected List<?> getFieldOrder() {
return Arrays.asList(new String[] { "cbMaxToken",
"cbMaxSignature",
"cbBlockSize",
"cbSecurityTrailer"
});
}
}
And so forth for the few definitions I need.
Ultimately the goal was to get the MakeSignature call to work (the QueryContextAttributes(...) being a precursor), and I had trouble leveraging the default JNA SecBufferDesc structure. I found a pointer to a solution from JSch SSPI by Joe Khoobyar, and leveraged the basic definition from that site, changing the NativeLong objects to int, and adding the new required method getFieldOrder().
The MakeSignature method, following definitions from Microsoft, was defined in the Interface as:
public int MakeSignature(CtxtHandle phContext,
int fQOP,
ISecur32.SecBufferDesc pMessage,
int messageSeqNo);
After using the above methods for QueryContextAttributes and the modified structure for SecBufferDesc, I was able to get a working solution. The Java clients may now leverage the Microsoft SSPI system for SSO to the remote Linux machines.
Hello I want to do a really simple thing. Just make a template function for any numbers. I actually want as little as ability to "add". In C++ it would be really trivial like this:
template <typename T>
inline T add (T a, T b) {
return a + b;
}
int main(int argc, char** argv){
printf("int: %d\n",add(1,2));
printf("float: %f\n",add(1.1,2.1));
}
In Java I got a tough lesson. I'm new to Java so I believe (and hope) I'm totally wrong and over engineering this. But only thing I come up with was:
public interface IntrfcWowNumbersAdds<T> {
T add(Number v);
}
public class SuperSmartInteger extends Number implements IntrfcWowNumbersAdds<SuperSmartInteger>{
private Integer i;
public SuperSmartInteger(int v) {
i = v;
}
#Override
public String toString(){
return ""+i;
}
#Override
public SuperSmartInteger add(Number v) {
return new SuperSmartInteger(this.intValue()+v.intValue());
}
#Override
public int intValue() {
return i; // thx god for auto(un)boxing
}
#Override
public long longValue() {
return i;
}
#Override
public float floatValue() {
return i;
}
#Override
public double doubleValue() {
return i;
}
}
And note that this crazy wrapper above I would have to do for any number I would like to use template for (eg double, byte etc...)
public class ThreadSafeNum<T extends Number & IntrfcWowNumbersAdds<T>> {
private T num;
public ThreadSafeNum(T n){
num = n;
}
public T add(T v){
// note in here I plan to do some locking...
return num = num.add(v);
}
}
then I can use it as:
SuperSmartInteger i = new SuperSmartInteger(5);
SuperSmartInteger i2 = i.add(6);
System.out.println(""+i2);
ThreadSafeNum<SuperSmartInteger> tsn = new ThreadSafeNum<SuperSmartInteger>(i);
SuperSmartInteger i3 = tsn.add(i2);
I know that when add() would be only adding I can just use + operator and rely on auto(un)boxing. But my add() method is meant to do something extra (like lock).
So how to do it properly? Or is my way correct???
Something like this as the base class:
public abstract class Addable<T extends Number,U extends Addable<T,U>> {
private final T value;
public Addable( final T value ){ this.value = value; }
public T getValue(){ return value; }
public abstract U add( U addend );
}
And this as the sub-class:
public class AddableInteger extends Addable<Integer,AddableInteger> {
public AddableInteger( final Integer value ){
super( value );
}
#Override
public AddableInteger add( final AddableInteger addend ){
java.util.Objects.requireNonNull( addend );
return new AddableInteger( this.getValue() + addend.getValue() );
}
}
Well, the reasons that works in C++ is that the compiler will create as many functions as there are calls in the code, and compile each one independently in order to validate if '+' is a reasonable thing to do in that particular case. This is a little like a case of compiler-assisted duck-typing. In other words, there is no guarantee that type T will have a + operator and only the fact that the compiler will look at the actual call types and create permutations helps you.
Note that there is some risk in letting the compiler "add whatever", since there is no interface or contract that guarantees the semantics to be correct. That is what a class hierarchy brings you.
This is trickier to do in full type safety since inheritance can be complex and the return types need to be somewhat clear. Inheritance is the usual thing so that a virtual method knows how to add its own type, but in this case you can't change the class hierarchy of Number.
You can, nevertheless, do something like this:
public static int addAsInt(Number a, Number b)
{
a.intValue() + b.intValue();
}
And the same for other return types. That will take any two instances of number and generate an output value, assuming which kind of output type you want. Somewhat easier than creating wrapper classes in this particular case.
I've seen a question similar to this multiple times here, but there is one big difference.
In the other questions, the return type is to be determined by the parameter. What I want/need to do is determine the return type by the parsed value of a byte[]. From what I've gathered, the following could work:
public Comparable getParam(String param, byte[] data) {
if(param.equals("some boolean variable")
return data[0] != 0;
else(param.equals("some float variable") {
//create a new float, f, from some 4 bytes in data
return f;
}
return null;
}
I just want to make sure that this has a chance of working before I screw anything up. Thanks in advance.
I don't know what these people are talking about. You lose type safety, which is a concern, but you could easily accomplish this with generics...something like:
public <T> T getSomething(...) { }
or
interface Wrapper<T> { T getObject(); }
public <T> Wrapper<T> getSomething(...) { }
The latter promotes the possibility of a strategy pattern. Pass the bytes to the strategy, let it execute and retrieve the output. You would have a Byte strategy, Boolean strategy, etc.
abstract class Strategy<T> {
final byte[] bytes;
Strategy(byte[] bytes) { this.bytes = bytes; }
protected abstract T execute();
}
then
class BooleanStrategy extends Strategy<Boolean> {
public BooleanStrategy(byte[] bytes) { super(bytes); }
#Override
public Boolean execute() {
return bytes[0] != 0;
}
}
Your example code is a bad use case though and I wouldn't recommend it. Your method doesn't make much sense.
This CAN be done. The following code will work:
public byte BOOLEAN = 1;
public byte FLOAT = 2;
public static <Any> Any getParam(byte[] data) {
if (data[0] == BOOLEAN) {
return (Any)((Boolean)(boolean)(data[1] != 0));
} else if (data[0] == FLOAT) {
return (Any)((Float)(float)data[1]);
} else {
return null;
}
}
By using a generic for the return type any Java method can dynamically return any object or primitive types. You can name the generic whatever you want, and in this case I called it 'Any'. Using this code you avoid casting the return type when the method is called. You would use the method like so:
byte[] data = new byte[] { 1, 5 };
boolean b = getParam(data);
data = new byte[] { 2, 5 };
float f = getParam(data);
The best you can do without this trick is manually casting an Object:
float f = (float)getParam(data);
Java dynamic return types can reduce boilerplate code.
You can't do it. Java return types have to be either a fixed fundamental type
or an object class. I'm pretty sure the best you can do is return a wrapper type
which has methods to fetch various possible types of values, and an internal enum
which says which one is valid.
--- edit --- after Danieth's correction!
public <Any> Any getParam(boolean b){
return((Any)((Boolean)(!b)));
}
public <Any> Any getParam(float a) {
return((Any)((Float)(a+1)));
}
public <Any> Any getParam(Object b) {
return((Any)b);
}
public void test(){
boolean foo = getParam(true);
float bar = getParam(1.0f);
float mumble = getParam(this); // will get a class cast exception
}
You still incur some penalties for boxing items and type checking
the returned values, and of course if your call isn't consistent with
what the implementations of getParam actually do, you'll get a class
cast exception.
My 2 cents with an example with Google HTTP client:
static public <Any> Any getJson(final String url, final Class<Any> parseAs) throws IOException {
HttpRequestFactory requestFactory
= HTTP_TRANSPORT.createRequestFactory(
(HttpRequest request) -> {
request.setParser(new JsonObjectParser(JSON_FACTORY));
});
HttpRequest request = requestFactory.buildRequest(HttpMethods.GET, new GenericUrl(url), null);
return request.execute().parseAs(parseAs);
}
Can be use like this:
HashMap<String, Object> out = HttpUtils.getJson( "https://api.qwant.com", HashMap.class);
If you are really only returning a boolean or a float, then the best you can do is Object.
If you are returning variable objects, you have to choose a return type with the least common superclass. Primitives don't have a superclass, but they will be boxed into Object representations (like Boolean and Float) which have a common superclass of Object.
It can also be done as the below example:
public class Test
{
public <T> T dynamicReturnMethod(Class<T> clazz)
{
//your code
return class.getDeclaredConstructor().newInstance();
}
//usage
public static void main(String[] args)
{
Test t = new Test();
ClassObjectWhichNeedsToBeReturned obj =
t.dynamicReturnMethod(ClassObjectWhichNeedsToBeReturned.class)
}
}
This has been tested using java 11