I have a XmlParserException while trying to request a list of object in MinIO, I don't understand why, i've done many research but i wasn't able to find an answer, here is what I've done:
public void minioListener() {
AvroParserService avroParserService = new AvroParserService();
try {
List<String> downloadedObjects = new ArrayList<String>();
while(true) {
Iterable<Result<Item>> objects = getListObjects();
for (Result<Item> result : objects) {
Item object;
object = result.get();
if(!object.isDir() && object != null) {
String objectName = object.objectName();
if (!downloadedObjects.contains(objectName)) {
// Get object
InputStream objectStream = getMinioClient().getObject(GetObjectArgs.builder()
.bucket(minioConfig.getBucket())
.object(objectName)
.build()
);
avroParserService.deserialize(objectStream);
downloadedObjects.add(objectName);
// Traiter l'objet ici
}
}
}
}
}
catch (InvalidKeyException | ErrorResponseException | IllegalArgumentException
| InsufficientDataException | InternalException | InvalidResponseException
| NoSuchAlgorithmException | ServerException | XmlParserException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
And Here is the output:
io.minio.errors.XmlParserException: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character 'd' (code 100) after '<!' (malformed comment?)
at [row,col {unknown-source}]: [1,3]
at io.minio.Xml.unmarshal(Xml.java:55)
at io.minio.S3Base.lambda$getRegionAsync$2(S3Base.java:847)
at java.base/java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:646)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2147)
at io.minio.S3Base$1.onResponse(S3Base.java:559)
at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
It seems that the problem occur because I don't provide details for region, but in the example show on the MinIO Api documentation, they don't necessary provide region, (I can't provide region because it's not defined)
Related
I study reflection and try to change field's value in Record.
public record Account(Integer id, String login, Boolean blocked) {}
public class Main {
public static void main(String[] args) {
Account account = new Account(null, null, null);
setFieldValue(account, "id", 1);
setFieldValue(account, "login", "admin");
setFieldValue(account, "blocked", false);
System.out.println(account);
}
public static void setFieldValue(Object instance,
String fieldName,
Object value) {
try {
Field field = instance.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(instance, value);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
If I convert Record to Class everything works, but with Record I get Exception
java.lang.IllegalAccessException: Can not set final java.lang.Integer field Account.id to java.lang.Integer
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwFinalFieldIllegalAccessException(UnsafeFieldAccessorImpl.java:76)
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwFinalFieldIllegalAccessException(UnsafeFieldAccessorImpl.java:80)
at java.base/jdk.internal.reflect.UnsafeQualifiedObjectFieldAccessorImpl.set(UnsafeQualifiedObjectFieldAccessorImpl.java:79)
at java.base/java.lang.reflect.Field.set(Field.java:799)
What do I have to do to make the code work with records?
In general the commenters saying that this "can't be done" or is "impossible" aren't wrong... unless you are willing to slightly bend the rules of the JVM :) For example, by using unsafe reflection to change the relevant value directly at the memory location in the record like this:
public static void setFieldValue(Object instance, String fieldName, Object value) {
try {
Field f = instance.getClass().getDeclaredField(fieldName);
Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
Unsafe unsafe = (Unsafe) unsafeField.get(null);
Field theInternalUnsafeField = Unsafe.class.getDeclaredField("theInternalUnsafe");
theInternalUnsafeField.setAccessible(true);
Object theInternalUnsafe = theInternalUnsafeField.get(null);
Method offset = Class.forName("jdk.internal.misc.Unsafe").getMethod("objectFieldOffset", Field.class);
unsafe.putBoolean(offset, 12, true);
unsafe.putObject(instance, (long) offset.invoke(theInternalUnsafe, f), value);
} catch (IllegalAccessException | NoSuchFieldException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException e) {
e.printStackTrace();
}
}
I have the next Java code:
public static <T> T buildSAMLObject(final Class<T> clazz) {
T object = null;
try {
XMLObjectBuilderFactory builderFactory = XMLObjectProviderRegistrySupport.getBuilderFactory();
QName defaultElementName = (QName)clazz.getDeclaredField("DEFAULT_ELEMENT_NAME").get(null);
object = (T)builderFactory.getBuilder(defaultElementName).buildObject(defaultElementName);
} catch (IllegalAccessException e) {
throw new IllegalArgumentException("Could not create SAML object");
} catch (NoSuchFieldException e) {
throw new IllegalArgumentException("Could not create SAML object");
}
return object;
}
I am trying to convert it to Scala and so far I got:
def buildSAMLObject(clazz: asInstanceOf[T]): [T] T {
var obj = builderFactory.getBuilder(defaultElementName).buildObject(defaultElementName).asInstanceOf[T];
try {
val builderFactory = XMLObjectProviderRegistrySupport.getBuilderFactory();
val defaultElementName = clazz.getDeclaredField("DEFAULT_ELEMENT_NAME").get(null).asInstanceOf[QName];
obj = builderFactory.getBuilder(defaultElementName).buildObject(defaultElementName).asInstanceOf[T];
} catch
{
case e: IllegalAccessException => throw new IllegalArgumentException("Could not create SAML object")
case e: NoSuchFieldException => throw new IllegalArgumentException("Could not create SAML object")
}
obj
}
The latter is not compiling and I believe this is because I do not know how to represent [T] T. Any suggestions, please?
Generics in method signature causes the error, it should go like this:
def buildSAMLObject[T](clazz: Class[T]): T = {
P.S.: In scala newline sumbol is an equivalent of semicolon, you don't need to write them.
Im trying to do something that might seem a bit unorthodox, however this is due to some limitations in a framework that im using.
Basically my case is this:
1: I have an object that has several fields, all with default values.
2: I have an other object that is initialized and has all values that I want to have, in the new object.
Im trying to do this with reflection, so looping over all public setMethods, finding all getMethods that seem to be matching from the other object, invoking them and invoke the other setMethod with the value over the invoked setMethod.
This is what I came up with so far:
java.lang.reflect.Method[] publicMethods1 = newlabels.getClass().getMethods();
for(int i=0; i<publicMethods1.length; i++){
if (publicMethods1[i].getName().startsWith("set")){
String setname = publicMethods1[i].getName();
String getname = "get"+setname.substring(3, setname.length());
try {
java.lang.reflect.Method getMethod = labels.getClass().getMethod(getname, null);
publicMethods1[i].invoke(newlabels, getMethod.invoke(labels, null));
} catch (NoSuchMethodException e1) {
//System.out.println("Couldnot find a method with name: "+getname);
} catch (SecurityException e1) {
//System.out.println("Security exception occured");
} catch (IllegalAccessException e1) {
//System.out.println("IllegalAccessException");
} catch (IllegalArgumentException e1) {
//System.out.println("IllegalArgumentException");
} catch (InvocationTargetException e1) {
//System.out.println("InvocationTargetException");
}
}
}
This unfortunately isn't working, its not giving errors either (unless a getter wasnt found, but ill take that).
I looked around on the internet and found somewhat similar in this method:
/**
* Only works for methods with equally named getters and setters
*
* 1. Get all declared methods of obj1 and find all setters
* 2. Get all declared methods of obj2 and find all getters
* 3. Find which setter belongs to which getter
* 4. Set the value of obj1.setter with obj2.getter
*
* #param obj1
* #param obj2
*/
public static void runAllSettersWithGetters(Object obj1, Object obj2) {
ArrayList<Method> setters = findSetters(obj1);
ArrayList<Method> getters = findGetters(obj2);
for(int s=0; s<setters.size(); s++){
String setmethodname = setters.get(s).getName();
String whattoset = setmethodname.substring(3);
for(int g=0; g<getters.size(); g++){
boolean isboolean = false;
boolean match = false;
if(getters.get(g).getReturnType().equals(Boolean.TYPE)){
isboolean = true;
}
String getmethodname = getters.get(g).getName();
String whattoget = getmethodname.substring(3);
if(whattoset.equalsIgnoreCase(whattoget)){
match = true;
}else{
//might start with is instead of get
whattoget = getmethodname.substring(2);
if(whattoset.equalsIgnoreCase(whattoget)){
match = true;
}
}
if(match){
try {
setters.get(s).invoke(obj1, getters.get(g).invoke(obj2));
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
So I tried it, because it seems better, however in the end it gives the same not working solution.
Can anyone help me with this?
I can't seem to be able to access the Exception in the method for a JUnit test. Here is the method:
public void doUpdateStocks() {
for (Entry<Integer, IFolioRestricted> e : folioList.entrySet()) {
IFolioRestricted folio = e.getValue();
for(Entry<Integer, IStockRestricted> s : folio.getStockList().entrySet()){
try {
((IStock) (s.getValue())).updatePrice();
} catch (MethodException e1) {
e1.printStackTrace();
}
}
}
And this is how I am testing it:
#Test
public void testUpdateStock() {
h.doCreateNewFolio("a");
try {
h.doBuyStock(0, "A", 10);
} catch (IOException | WebsiteDataException | NoSuchTickerException | MethodException e) {
// TODO Auto-generated catch block
}
h.doUpdateStocks();
}
After looking online I have seen (expected = MethodException.class) however it doesn't seem to work. Anyone any ideas on how to cover the catch (MethodException e1) { e1.printStackTrace(); } in a JUnit?
First of all, you will need to throw the exception in order to catch it in your JUnit test:
public void doUpdateStocks() throws MethodException { // throw the exception
for (Entry<Integer, IFolioRestricted> e : folioList.entrySet()) {
IFolioRestricted folio = e.getValue();
for(Entry<Integer, IStockRestricted> s : folio.getStockList().entrySet()){
((IStock) (s.getValue())).updatePrice();
}
}
You code should than work already, but you will have to fail the test, if no exception is thrown:
try {
h.doBuyStock(0, "A", 10);
// No exception thrown, thats wrong so fail the test
Assert.fail()
} catch (IOException | WebsiteDataException | NoSuchTickerException | MethodException e) {
// This is where you want to end
}
Besides throw the exception (which you definitely have to do), there is a better approach to handle exceptions on unit tests using https://github.com/Codearte/catch-exception
Look at the samples on github.
This is the code I'm working on which instantiates and creates object at run time with provided arguments for the constructor.
private static void createInstancesFromSpecfication() {
String[] specifierFileNames = resourceMap.get("instances");
if (null == specifierFileNames)
return;
List<SpecifierObjects> instances = new ArrayList<SpecifierObjects>();
for (int i = 0; i < specifierFileNames.length; i++) {
try {
instances.addAll(XMLFileUtility.readXML(specifierFileNames[i],
new ClassInstantiationHandler()));
} catch (ResourceNotAvailableException | DocumentException
| ResourceDataFailureException e) {
e.printStackTrace();
}
}
for (Iterator<SpecifierObjects> iterator = instances.iterator(); iterator
.hasNext();) {
InstanceSpecifierObject instanceSpecifierObject = (InstanceSpecifierObject) iterator
.next();
try {
Class<?> cast = Class.forName(instanceSpecifierObject
.getInterfaceName());
Class<?> clazz = Class.forName(instanceSpecifierObject
.getClassName());
Constructor<?> constructor = clazz
.getConstructor(String[].class);
Object obj = constructor.newInstance(instanceSpecifierObject
.getFilesName());
objects.put(instanceSpecifierObject.getObjectName(),
cast.cast(obj));
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException
| SecurityException e) {
e.printStackTrace();
}
}
}
The exception log is :
instances=/home/user/workspace/CoreLibs/src/instanceSpecification.xml
/home/user/workspace/CoreLibs/src/instanceSpecification.xml
java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at com.framew.confinit.ApplicationResource.createInstancesFromSpecfication(ApplicationResource.java:87)
at com.framew.confinit.ApplicationResource.importResource(ApplicationResource.java:58)
at com.framew.confinit.ApplicationResource.main(ApplicationResource.java:40)
I'm getting the exception in this statement:
Object obj = constructor.newInstance(instanceSpecifierObject.getFilesName());
instanceSpecifierObject.getFilesNames() retruns an array of filenames as String objects (like String[]). I also tried passing them as Object[], but got the same exception.
Any help is appreciated. Thanks in Advance.