How to initialize collection in one line? - java

I am creating my list like this and passing to a method withInitialListeners and then I don't see any compilation error and it works fine.
List<Host.StateListener> cassListener = new ArrayList<>(); // line 1
cassListener.add(new CassListener()); // // line 2
Builder clusterBuilder = Cluster.builder();
Cluster cluster =
clusterBuilder
.withInitialListeners(cassListener).build();
Now I was thinking to coming line1 and line2 in a single line and pass it directly to withInitialListeners method so I did something like this:
Builder clusterBuilder = Cluster.builder();
cluster =
clusterBuilder
.withInitialListeners(Arrays.asList(new CassListener())).build();
But with this approach it gives me compilation error as shown below:
The method withInitialListeners(Collection<Host.StateListener>) in the type Cluster.Builder is not applicable for the arguments (List<CassListener>)
What is wrong and how can I fix it? I am working with Java 7.

Ideally, you should change the signature of withInitialListeners to withInitialListeners(Collection<? extends Host.StateListener>).
If that is not an option, you can force the generic types of a method by placing explicit types in <…> before the method call:
Arrays.<Host.StateListener>asList(new CassListener())
As you can see, it’s pretty weird to write, and it may befuddle future developers who have to maintain it. The first option is preferred. But sometimes, explicit generic typing is unavoidable.

Related

How to declare a variable to get an output as a Sub parameter using Jacob

I am using Jacob to call VBA COM interfaces in software.
I need to call a Sub that has an output parameter, that is not of canonical type (int, String, etc.) but of some dedicated interface declared in .tlb that are brought with this software.
Here is the
Sub GetMaterialOnBody (Body iBody, Material oMaterial)
So I tried many declarations and initializations for the output parameter material in the call, I get various errors and cannot seem to find the proper way to do.
Variant material = new Variant (null, false);
Dispatch.invoke(materialManager.getDispatch(), "GetMaterialOnBody", Dispatch.Method, new Object[] {hybridBody, material}, new int[1]);
but got
com.jacob.com.ComFailException: A COM exception has been encountered:
At Invoke of: GetMaterialOnBody
Description: Type mismatch.
Then I tried to call .getDispatch() on material
Variant material = new Variant (null, false);
Dispatch.invoke(materialManager.getDispatch(), "GetMaterialOnBody", Dispatch.Method, new Object[] {hybridBody, material.getDispatch()}, new int[1]);
but got
java.lang.IllegalStateException: getDispatch() only legal on Variants of type VariantDispatch, not 0
So I tried
Variant material = new Variant (null, false);
material.putNothing();
Dispatch.invoke(materialManager.getDispatch(), "GetMaterialOnBody", Dispatch.Method, new Object[] {hybridBody, material.getDispatch()}, new int[1]);
but got
com.jacob.com.ComFailException: putObject failed
at com.jacob.com.Variant.putVariantDispatch(Native Method) ~[jacob-1.14.3.jar:na]
at com.jacob.com.Variant.putDispatch(Variant.java:1341) ~[jacob-1.14.3.jar:na]
I tried different solutions, including using Ref, etc.
I am a bit lost on how exactly we have to initialize a variant/dispatch to pass as an output parameter in a Sub.
Does anyone have any clue on how to do that? The closes resources I found were handling String/Integer and not object.
This old question might be related (but obviously no answer): https://community.oracle.com/tech/developers/discussion/1548970/jacob-out-parameters-refs-in-jni
I have open a question on the jacob github
https://github.com/freemansoft/jacob-project/issues/23
Also I emailed the owner of the project on github and he said the project was dormant for some time already. As all the code is available I will take the time to compile and debug the native (C++) side in order to debug my case. I will update that question then.
if that is output parameter, shouldn't it be 'ByRef' ?
Sub GetMaterialOnBody (Body iBody, ByRef Material oMaterial)
In your case probably GetMaterialOnBody sub is expected to fill in internals of oMaterial object, not to set reference to it? Then just create an empty Material object and pass to the sub

In JMeter java api how to set POST Form values in a PreProcessor sampler?

In a PreProcessor I am writing I can successfully update GET query string via sampler.
However if I use the same approach with POST, while I can list the FORM fields via getArguments(), the value does not get set.
Arguments arguments = sampler.getArguments();
for (int i=0; i<arguments.getArgumentCount(); i++) {
Argument argument = arguments.getArgument(i);
if (argument.getName().equals("page_submission_id")) {
String newVal = "8743718386872";
argument.setValue(newVal);
System.out.println("Setting arg["+argument.getName()+"] to["+newVal+"]");
}
}
sampler.setArguments(arguments);
printArgs(arguments);
The output from this shows Arguments values are unchanged.
Setting arg[page_submission_id] to[8743718386872]
Arguments After
...
Found arg[page_submission_id] is[XXXXXXXXXXXXX]
...
Having dug into the jmeter code a bit further, there is a "runningVersion" attribute of an Attribute object which (via isRunningVersion()) is set true.
I have tried a few ways to get round this:
force runningVersion to false - then values are set but a GET message is sent
create a new Arguments object and add new Argument entries to it with values - this does not change the values
Can anyone point out the official way to set POST FORM field values before they get sent?
Thanks
Well, you assigning a new value to an argument, but I fail to see where you updating sampler's arguments with the argument having the new value.
I'm a strong believer of KISS principle so instead of adding some more lines I would recommend simplifying your script as follows:
import org.apache.jmeter.config.Argument;
sampler.getArguments().removeArgument("page_submission_id");
sampler.addArgument("page_submission_id","8743718386872");
Also I hope you're using JSR223 PreProcessor and Groovy language.
I managed to resolve this:
(initially) by cleaning up the Thread Pool, as my initial
attempts had included a number of things like "Regular Expression
Extractors" and "User defined variables". Once those were removed
the approach I was using successfully changed the argument values, and
(when deeper in to my setup the problem came back) by adding the creation of a new Argments object and inserting (in the same order) new Argument objects with the value set as I require. Then setting the sampler to use that new Arguments object.
Arguments newArgs = new Arguments();
Arguments arguments = sampler.getArguments();
for (int i=0; i<arguments.getArgumentCount(); i++) {
Argument argument = arguments.getArgument(i);
HTTPArgument newArg = new HTTPArgument();
newArg.setName(arguments.getName());
if (arguments.getName().equals("field_to_replace")) {
newArg.setValue("new value");
}
else {
newArg.setValue(arguments.getValue());
}
newArgs.addArgument(newArg);
}
sampler.setArguments(newArgs);
My take is that this down to the "if (isRunningVersion())" test within setProperty() used by "Argument.setValue()" which I'm tripping over.
While this appears to work (for my test cases so far) I appreciate that overriding this may not be the correct formal approach.

Why sometimes it gives exception but sometimes doesn't?

My program has two parts, one data structure and second operations.
Data Structure part is, basically and object & set of that object. This set is a class that extends ArrayList. Set and Objects are unique, what I mean is if I have a class named A then I have aSet which keeps the all A objects in it.
Operation part is doing some operations on those sets and most of the times it is also creates a new class in the runtime (write the class in a java file and compile it then call it from Reflect library functions e.g. constructor.newInstance(args);) and creates an object from new class then fill inside of it and return it. Since I didn't wanted to overwrite classes I use UUID trimmed for naming the new classes that created at the runtime.
I had noticed something odd. I run my code and it works, then I run it again and at the creation of set, it gives me "java.lang.IllegalArgumentException: wrong number of arguments". I run it again exception, again and again then I run it again then no exception. (Every time it created a new class like I wanted)
So why my code can act like this?
I am using Oracle Java 1.8 on Ubuntu 14.04 with Intellij Idea (tried also Eclipse no change).
Edit for code:
"I removed the codes unrelated to the problem"
And this is the part that gives error at my operation; (Initial innerInnerName is the random generated class name)
final String outerClassName = "" + initialInnerName + "Table";
final String innerClassName = "" + initialInnerName;
File file = new File("./src/");
URL url = file.toURI().toURL();
URL urls[] = new URL[]{url};
URLClassLoader loader1 = new URLClassLoader(urls);
Class<?> innerClass = loader1.loadClass(innerClassName);
Set<Template> newTable = null;
Class<?> outerClass = loader1.loadClass(outerClassName);
Constructor<?> constructorOfOuterClass = outerClass.getDeclaredConstructors()[0];
Object[] objArg = {innerClass,10};
newTable = (Set<Template>) constructorOfOuterClass.newInstance(objArg);
Edit 2
Exception being thrown at last line of last code which is:
newTable = (Set<Template>) constructorOfOuterClass.newInstance(objArg);
Well I had tried to do MCVE as much as possible.
Your "Outer Class" has two constructors, one that takes one argument and one that takes two. When you go to instantiate the outer class, you get the first in the list of constructors:
Constructor<?> constructorOfOuterClass = outerClass.getDeclaredConstructors()[0];
and then you try to invoke it with two arguments:
Object[] objArg = {innerClass,10};
newTable = (Set<Template>) constructorOfOuterClass.newInstance(objArg);
The problem is that the constructors aren't necessarily in the order you expect. No particular order is guaranteed, so sometimes you will get the one argument constructor and sometimes the two argument constructor. When you get the two argument constructor, all is well. But when you get the one argument constructor and invoke it with two arguments, well, you know all too well what happens then.
You need to determine which of the constructors is the one you want, and select it, rather than assuming that it is the first one in the list.

Crossjoin in Cascading

I'd like to crossjoin two streams of tuples in Cascading. Let's suppose there are two lists: ladies and gentlemen, and the goal is to write all the possible lady-gentleman combinations out to a file (e.g. all the possible matches from the "women seeking men" section of a hypothetical dating website).
I found a similar example on this blog and attempted to tweak the code to make a crossjoin (see https://github.com/alexwoolford/cascading-crossjoin-stackoverflow-question).
The operate method in the Crossjoin class throws a null-pointer. Firstly, the getJoinerClosure() call in this line returns null:
JoinerClosure joinerClosure = bufferCall.getJoinerClosure();
... and then the if statement that immediately follows tries to get the size of null:
if( joinerClosure.size() != 2 )
[...]
... resulting in a null-pointer exception.
Can you see where I'm going wrong?
It worked when I removed the rhsGroupFields argument from the new CoGroup constructor, i.e. changed from:
Pipe pipeLadiesAndGentlemen = new CoGroup(pipeLadies, Fields.NONE, pipeGentlemen, Fields.NONE, new Fields("lady", "gentleman"), new BufferJoin());
.. to:
Pipe pipeLadiesAndGentlemen = new CoGroup(pipeLadies, Fields.NONE, pipeGentlemen, Fields.NONE, new BufferJoin());

Knowing what the contents of variables are going to be, how do I determine what to place inside the <> to eliminate "raw type" warnings?

I’m working on a program that utilizes evolutionary algorithms. This program was written prior to the introduction of Java generics. One of the many tasks I’ve been given is to remove the “raw type” warnings this legacy code is producing.
I’ve looked at several Java reference books and read all the answers to questions concerning the removal of these type warnings and haven’t found what I’m looking for. I can’t simply add the ? wildcard to the variable declarations to remove the warnings unless that is the only valid solution.
Here is an example snippet of code that is issuing warnings. Knowing what the contents of the three variables that are issuing the “raw type” warnings are going to be, how do I determine what to place inside the <> to eliminate the warnings?
Thanks in advance.
/**
* Uses the information from the configuration file to instantiate
* the right classes for the environment, statistics, algorithm slots
*/
private void reificate() {
try{
Raw type warning --> Class c = null;
Raw type warning --> Class params1 [] = new Class[1];
Raw type warning --> java.lang.reflect.Constructor cons = null;
Object [] params2 = new Object[1];
// Instantiating a configuration object
c = Class.forName(cfgSB.toString());
params1[0] = Class.forName("java.lang.String");
cons = c.getConstructor(params1);
params2[0] = new String(cfgFileName);
cfg = cons.newInstance(params2);
(The following code will require additional Class type variables to be declared, but if I can
learn how to eliminate the warnings above, I’ll know how to declare the new variables properly.)
// Instantiating an environment
c = Class.forName(envSB.toString());
params1[0] = Class.forName("jade.core.Config");
cons = c.getConstructors()[0];
params2[0] = cfg;
env = cons.newInstance(params2);
// Instantiating an Algo object to run
c = Class.forName(algSB.toString());
cons = c.getConstructors()[0];
params2[0] = cfg;
alg = (jade.core.EvolAlgo)cons.newInstance(params2);
// Creating statistics object and attaching it to cfg
// This has to be done last since statistics constructor is
// going to refer to the population of Algo via a local attribute C
c = Class.forName(staSB.toString());
cons = c.getConstructors()[0];
params2[0] = cfg;
sta = (jade.stats.Statistics)cons.newInstance(params2);
// ********************* end of snippet **************************//
Class.forName() returns Class<?>, see documentation.
It can't return a Class<String> even when you specify java.lang.String since there is no mapping between the string name and the actual class at compile time.
The same applies to constructors, parameters, .. You can only specify a concrete class type if you have a real runtime type (obtainable via String.class for example).
I'd do it roughly like:
jade.core.Config cfg = (jade.core.Config) Class.forName(cfgSB.toString())
.getConstructor(String.class)
.newInstance(cfgFileName);
// not sure what type that is..
Object env = Class.forName(envSB.toString())
.getConstructor(jade.core.Config.class)
.newInstance(cfg);
jade.core.EvolAlgo alg = (jade.core.EvolAlgo) Class.forName(algSB.toString)
.getConstructor(jade.core.Config.class)
.newInstance(cfg);
jade.stats.Statistics sta = (jade.stats.Statistics) Class.forName(staSB.toString())
.getConstructor(jade.core.Config.class)
.newInstance(cfg);
There is no need to create extra arrays, the methods take a comma separated list of things (varargs). You also don't need to specify forName("java.lang.String") since you can use the actual type here. And since you seem to know the type, you can use the getConstructor method instead of hoping that the first constructor is the correct one.

Categories