How do I debug generic methods in Eclipse? - eclipse

I'm in a generic method, debugging, but i get no information about variables, can't execute statements using ctrl-shift-i, eclipse tells the that the method ... isn't available on the type T.
I can't believe it's meant to (not) work like this ...
[edit]
I'm using the eclipse that's part of RAD 7.5.4
[another edit]
Here's some code but I doubt you'll get any info from this
public abstract class GenericGroupController<T extends Group> {
...
public String addUser(final Model model, final Long id, final WebRequest request) {
T group = groupManager.loadGroup(id);
...
// this method will fail if i highlight and click ctr-shift-i
// but it will work otherwise (actually so will the method above
// because that's generic as well)
Long groupId = group.getId();
...
return getAddUserView();
}
}

If you are able to debug, as in see a stack trace, you can always see the variables in the variables window if not in the code. A lot of places where the code isn't available you can do the same. It isn't nice, but, it gets the job done.

Related

In Katalon Studio, How to retrieve the values using the javascript executor. document.getElementsByTagName('input')[29].value

enter image description here
I tried below code but not works.
a = WebUI.executeJavaScript('document.getElementsByTagName("input")[29].value', null)
Thread.sleep(5000)
System.out.println(a)
There is so much wrong with this question that I don't even know where to begin...
What are you trying to accomplish by using JavaScript (this is a testing code smell, for 99% of testing cases) to fetch a value ?
Why not do the following:
create a TestObject, preferably in the Object Repository, that points to the object in question.
give that Test Object the locator. This is, by default, some xpath.
In your case, give it xpath
(//input)[29]
. However, I advise you come up with a more meaningful selector for it (for example, select it by some class, data-* attribute, name) that is easier to maintain
use the built-in Keyword for getting attribute, like this:
WebUI.getAttribute(findTestObject('[whateverYourTestObjectNameIs]'), 'value')
this is just good code design, but write this to some Custom Keyword for this util:
// import statements here. Ctrl + Shift + O on your keyboard to bring those in
public final class GeneralWebUIUtils {
public static final String Value = "value";
public static final String GetValue(TestObject to) {
return WebUI.getAttribute(to, this.Value);
}
}
Also, why are you pausing runtime by some hard-coded time amount? That is a testing code smell. Stop it!
What exactly are you waiting on? Use the WebUI keywords for this thing you are waiting on, and if none of those suffice, hmu and I may have the wait method you're looking for ....
Oh, and looking at that image you linked, it looks like you solved your own question.

Eclipse call hierarchy lambda

I think 5 years has passed since Lambda has been released for Java.
public static void main(String[] args) {
go();
}
private static void go() {
Set<String> set = new HashSet<>();
set.stream().forEach((s) -> {
inner(s);
});
}
private static void inner(String s) {
inner1(s);
}
private static void inner1(String s) {
}
When I press CTRL-ALT-H - (open call hierarchy) on inner1 method, I expect to see a whole stack trace from in inner1 to main method. Instead, my staktrace is trimmed on inner method. I've just downloaded the newest Eclipse, I think it 2018-12, previously I was using Mars.
Intellij can show me the expected call-hierarchy, and I don't really understand why Eclipse still can't do it. Not sure if anyone else is using Eclipse in 2019, but maybe you can advise a plugin or something.
Switching to Intellij is not an option, I tried couple of times, but the habit is hard to overcome.
UPDATE
There is similar - SO question
At run time, evaluation of a lambda expression is similar to
evaluation of a class instance creation expression, insofar as normal
completion produces a reference to an object. Evaluation of a lambda
expression is distinct from execution of the lambda body.
and
Just note, that for lambdas implementing library types like
Consumer, the number of callers into accept(T) in a workspace may
easily become unmanageable, similar to any call hierarchy through,
e.g, Runnable.run() - but that doesn't question the general usefulness
of call hierarchies through lambdas.
I don't really care about lambda internals, somehow other IDE is able to show expected stacktrace
There's an existing old bug for eclipse, reported in 2016, still in NEW status
Bug 498498 - [1.8][search][call hierarchy] No usage for lambdas
Call hierarchy on bar method correctly shows usage in accept, and for accept there is no usage shown.
This issue was already present in mars.
There are 3 votes to fix it, you can vote too
From your edit's links there's another relevant old bug in NEW status
Bug 468561 - [search]Call Hierarchy stops searching in doubly-nested lambda chain
with 3 votes too...
Eclipse 4.22 (Q4 2021) should help:
Improved lambda support in the Call Hierarchy view
The Call Hierarchy view is enhanced with showing not only the callers of the lambda function, but the callers of the declaring function too.
For the following code:
Checking the callers of the function() will show this:
The [declaration] node in the tree is the new addition, which shows the callers of the definer() function, in this case, only the main() function.

Annotations containing lambda expressions in Java 8

I am experimenting with static fields in annotations and I am stumbling upon something I do not understand.
I use the following code:
#a
public class myAnnotMinimal {
public static void main(String[] args) {
System.out.println(myAnnotMinimal.class.getAnnotations().length);
}
}
#Retention(RetentionPolicy.RUNTIME)
#interface a {
Consumer<Integer> f1 = a -> {return;}; // -> 0
//Consumer<Integer> f2 = new B(); //-> 1
//Consumer<Integer> f3 = C::eat; //-> 1
//int f4 = 5; //->1
//Supplier<Integer> f5 = ()->5; //->1
}
class B implements Consumer<Integer> {
#Override
public void accept(Integer t) {
}
}
class C{
public static void eat(Integer t){
}
}
Now, when running this I would expect '1' to be printed, however, the output I get is '0'. When I remove the f1 field and uncomment the other (f2-f5) fields the output is '1'. To me this pretty much looks like a bug. Is there something I am missing? I use jdk1.8.0_66 on linux.
Since this looks like a bug in the JDK I filed a bug report. By now the bug report has been accepted. See http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8147585 .
This is a bug in the JRE’s annotation processing or, more precisely, its code hasn’t updated properly to accommodate the new language features, though it’s understandable that such usage hasn’t been considered.
Annotations are not supposed to provide utility methods and the ability to declare constants, i.e. fields that are implicitly public static final, should not be abused to add functions which carry code.
The reason for the bug is that certain Java language constructs produce synthetic methods behind the scenes. Field initializers may add code to a static method <clinit> at bytecode level, which is known and ignored by Reflection, thus creates no problems. That’s why Consumer<Integer> f2 = new B(); works (as it would do before Java 8), the creation happens inside this class initialization method. Note that int f4 = 5; creates a compile-time constant which does not need initialization code at all.
However, lambda expressions are compiled into synthetic methods which apparently are not ignored by the runtime Annotation implementation, despite being private, but checked for conformance with the standard annotation methods.
That’s why Supplier<Integer> f5 = ()->5; creates no problems, the synthetic method incidentally conforms to the annotation method pattern, as it has no parameters and returns a value. In contrast, Consumer<Integer> f1 = i->System.out.println(i); is compiled into a synthetic method having one parameter and void return type. This seems to cause the Annotation processing facility to reject that annotation as invalid (without reporting it).
In contrast, most method references do not need a synthetic helper method as they direct to the target method, thus Consumer<Integer> f3 = C::eat; creates no problems. You can verify this pattern by changing the declaration of f1 to Consumer<Integer> f1 = System.out::println;, while being semantically equivalent, the problem disappears, as now there’s no offending synthetic method in the annotation class file.
While this is indeed a bug, as, when when the Java language accepts lambda expression inside annotation fields, the JRE implementation should catch up to handle that scenario, I strongly discourage you from adding code to annotation types that way. Saving a single utility class is not worth that code smell. Also keep in mind that this creates additional runtime overhead compared to ordinary utility methods.

Method refactor in Intellij Idea and/or Eclipse

I have many classes (45 at least). Each one has its own method to validate something that is repeated in all the classes, so I have the code repeated in all those classes. I'd like to have one method and call it from all the classes.
If have the following code to know if a mobile device is connecting to the server
private boolean isMobileDevice(HttpServletRequest request) {
String userAgent = request.getHeader("user-agent");
return userAgent.indexOf("Windows CE") != -1;
}
As said before, This method is repeated in many classes
Is it possible in Intellij Idea and/or Eclipse to do that refactor? and How can I perform that refactor?
private boolean isMobileDevice(HttpServletRequest request) {
String userAgent = request.getHeader("user-agent");
return userAgent.indexOf("Windows CE") != -1;
}
I bet that my Eclipse will warn me that this method can be declared as static, because it does not use any fields of enclosing class - such method should be declared as static to let you know that it is not essentially needed in enclosing class, and if there will be a reason (having 45 methods in place of one is THE REASON) you can move it to some other class, and just call it as public or package method.
EDIT: It did: The method isMobileDevice(HttpServletRequest) from the type Test can be declared as static:
So:
Copy it to some other class, make it public static boolean isMobileDevice(HttpServletRequest request) and use in every classes where it was private boolean.
That's all, but I don't see and way to make it with automatic refactor.
With Intellij you could try "Refactor" > "Find and Replace Code Duplicates...".
It will replace the duplicate code by a static function.

Class design: file conversion logic and class design

This is pretty basic, but sort of a generic issue so I want to hear what people's thoughts are. I have a situation where I need to take an existing MSI file and update it with a few standard modifications and spit out a new MSI file (duplication of old file with changes).
I started writing this with a few public methods and a basic input path for the original MSI. The thing is, for this to work properly, a strict path of calls has to be followed from the caller:
var custom = CustomPackage(sourcemsipath);
custom.Duplicate(targetmsipath);
custom.Upgrade();
custom.Save();
custom.WriteSmsXmlFile(targetxmlpath);
Would it be better to put all the conversion logic as part of the constructor instead of making them available as public methods? (in order to avoid having the caller have to know what the "proper order" is):
var custom = CustomPackage(sourcemsipath, targetmsipath); // saves converted msi
custom.WriteSmsXmlFile(targetxmlpath); // saves optional xml for sms
The constructor would then directly duplicate the MSI file, upgrade it and save it to the target location. The "WriteSmsXmlFile is still a public method since it is not always required.
Personally I don't like to have the constructor actually "do stuff" - I prefer to be able to call public methods, but it seems wrong to assume that the caller should know the proper order of calls?
An alternative would be to duplicate the file first, and then pass the duplicated file to the constructor - but it seems better to have the class do this on its own.
Maybe I got it all backwards and need two classes instead: SourcePackage, TargetPackage and pass the SourcePackage into the constructor of the TargetPackage?
I'd go with your first thought: put all of the conversion logic into one place. No reason to expose that sequence to users.
Incidentally, I agree with you about not putting actions into a constructor. I'd probably not do this in the constructor, and instead do it in a separate converter method, but that's personal taste.
It may be just me, but the thought of a constructor doing all these things makes me shiver. But why not provide a static method, which does all this:
public class CustomPackage
{
private CustomPackage(String sourcePath)
{
...
}
public static CustomPackage Create(String sourcePath, String targetPath)
{
var custom = CustomPackage(sourcePath);
custom.Duplicate(targetPath);
custom.Upgrade();
custom.Save();
return custom;
}
}
The actual advantage of this method is, that you won't have to give out an instance of CustomPackage unless the conversion process actually succeeded (safe of the optional parts).
Edit In C#, this factory method can even be used (by using delegates) as a "true" factory according to the Factory Pattern:
public interface ICustomizedPackage
{
...
}
public class CustomPackage: ICustomizedPackage
{
...
}
public class Consumer
{
public delegate ICustomizedPackage Factory(String,String);
private Factory factory;
public Consumer(Factory factory)
{
this.factory = factory;
}
private ICustomizedPackage CreatePackage()
{
return factory.Invoke(..., ...);
}
...
}
and later:
new Consumer(CustomPackage.Create);
You're right to think that the constructor shouldn't do any more work than to simply initialize the object.
Sounds to me like what you need is a Convert(targetmsipath) function that wraps the calls to Duplicate, Upgrade and Save, thereby removing the need for the caller to know the correct order of operations, while at the same time keeping the logic out of the constructor.
You can also overload it to include a targetxmlpath parameter that, when supplied, also calls the WriteSmsXmlFile function. That way all the related operations are called from the same function on the caller's side and the order of operations is always correct.
In such situations I typicaly use the following design:
var task = new Task(src, dst); // required params goes to constructor
task.Progress = ProgressHandler; // optional params setup
task.Run();
I think there are service-oriented ways and object-oritented ways.
The service-oriented way would be to create series of filters that passes along an immutable data transfer object (entity).
var service1 = new Msi1Service();
var msi1 = service1.ReadFromFile(sourceMsiPath);
var service2 = new MsiCustomService();
var msi2 = service2.Convert(msi1);
service2.WriteToFile(msi2, targetMsiPath);
service2.WriteSmsXmlFile(msi2, targetXmlPath);
The object-oriented ways can use decorator pattern.
var decoratedMsi = new CustomMsiDecorator(new MsiFile(sourceMsiPath));
decoratedMsi.WriteToFile(targetMsiPath);
decoratedMsi.WriteSmsXmlFile(targetXmlPath);