I'm trying to find a way in IntelliJ IDEA to find all the usages of a few library method calls and classes in a particular project.
The goal is to compile a list of classes which make reference to these specific methods or classes.
How can I go about this, I can see there is a MethodReferencesSearch which looks like it could be helpful, however the search method requires an instance of PsiMethod.
How can I create an instance of PSI method that matches the method in a particular lib class (say I wanted to find all the usages of the concat(...) method in Java's String class
Basically I'm trying to build a plugin that will generate a graph of certain method calls from within a project. For example something that would graph a set of routes by looking for certain method calls in a library. I.e. if Class A calls x(T) with type class B and class B calls x(T) with type of Class C, I would have a graph that looks like A -> B -> C etc. Find usages is great, it just doesnt work well for my needs.
You can get the true PsiMethod by JavaPsiFacade.getInstance(...).findClass("java.lang.String", ...allScope(...)).findsMethodByName("concat", false)[0]. This method can then be passed to MethodReferenceSearch.
I am presuming that you can't guarantee that you have a usage of concat easily available (for example, at the user's cursor position in an open document).
A hacky way to do it would be to create a small, correct, self-contained java class in a String, like below:
class Nothing { String s = "a".concat("b"); }
Then, there is a way (if I remember correctly) to use IntelliJ to parse the class contained in this String, thereby giving you a PsiReference to the method you want to find usages on (in this case, concat).
Would this approach be useful to you?
If so, I can dig out a code example on how this can be done.
Related
I'm looking for a way of count how many different objects are being called inside a method using ByteBuddy for byte code analysis. I tried this with string parsing, but that's absolutely impossible. Also, I've checked about AST, but I should build the code before doing that, what would be a lot of time. By this, it would be preferable if I could create an agent.
Given the following code:
#Test
public void myMethod(){
Boolean myObj = false;
assertTrue(myObj).isTrue();
assertTrue(myObj2).isTrue();
}
The output for analysis for this method would be: (myObj, myObj2). As I'm new to JavaBuddy, my approach to this would be:
Create an element matcher that would find for methods annotated with #Test .
Intercept it
.... here's the problem: I don't know how should I count those objects or iterate through method statements.
Can anybody give me some links about it or samples?
In order to instrument code within a method, Byte Buddy allows you to use ASM to instrument the code instruction-wise. The reason for this is that ASM is a very good API for byte code processing already and there is no real good reason to replace it with something that would end up being rather similar.
If you want to learn about ASM, their webpage offers a great documentation.
Nevertheless, what you intend to is pretty complex to do. You basically have to follow the control flow of the method to see what object is assigned to what variable at any point in time. Also, some classes cannot be instrumented such as the Boolean class which is why I would recommend you to find another approach to your problem.
How can I instantiate an object of the class java.lang.Class from a given .java file?
I want to create an application to automatically generate JUnit tests. For that I would need "Method" objects and for "Method" objects I need to have a "Class" object.
java 6 onwards has an api for the compiler: http://www.javabeat.net/2007/04/the-java-6-0-compiler-api/
the link above includes an example.
here's another example - http://www.java2s.com/Code/Java/JDK-6/JavaCompilertoolshowyoucancompileaJavasourcefrominsideaJavaprogram.htm
to load the file once compiled you use a classloader. there's an example at http://tutorials.jenkov.com/java-reflection/dynamic-class-loading-reloading.html and another at http://www.javaworld.com/jw-10-1996/jw-10-indepth.html
you'd think there would be a library to simplify all this. i can't find one, but am still looking.
meanwhile, here's a really nice article from ibm that compiles a function and plots it - http://www.ibm.com/developerworks/java/library/j-jcomp/index.html
found one http://docs.codehaus.org/display/JANINO/Home - this is a library that simplifies the process. i would recommend configuring it to use the javax.tools API (see last sentence in the "what is Janino" paragraph).
sorry for the google snark earlier.
it just struck me that maybe you just want a class object.
if you have a class called MyClass then the associated class is Myclass.class. that's probably obvious, but perhaps that's all you need.
and if you have the class name in a string you can use this method - http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Class.html#forName(java.lang.String)
If you do know the full class String name, why don't you use the Class.forName(className) method to obtain the class Object?
For example, if the class name is yakam.yale.MyClass, just call the
Class.forName("yakam.yale.MyClass");
and the game is played!
Please see the attached image:
1) I downloaded a new library here: (http://www.java2s.com/Code/Jar/ABC/Downloadcommonslang24jar.htm)
2) In Eclipse, I right-clicked on 'Referenced Libraries' > Build Path > Configure Build Path > Add External JARs and added 'commons-lang-2.4.jar'
3) I've added import org.apache.commons.lang.* at the top of my class.
4) I entered a method from that class indexOfAny() and get the following error: 'The method indexOfAny() is undefined for the type String.'
What step(s) am I missing? Which steps that I've taken are unnecessary? I need to be able to use this method.
P.S. Pls ignore the rest of the code.
indexOfAny() is NOT a method on a String object.
Maybe you meant to write StringUtils.indexOfAny(...)
You're not using it right, you're trying to invoke the method indexOfAny() on a java.lang.String object - this method is not part of that class. You need to call these methods statically on org.apache.commons.lang.StringUtils - something of the form StringUtils.XXX()
The Commons Library doesn't augment existing classes (in any case, java.lang.String is final). According to the documentation, your call should be something that looks like:
StringUtils.indexOfAny(quantityInForPriceBandPopUp[i], ['z'])
or using one of the overloaded versions.
Update
Is importing the package necessary?
This article and the Java package trail should help with all the details of packages and imports. But some of the basic things to understand are :
Packages are the namespacing mechanism that Java uses - this allows you and I both to write a Utils class while avoiding a collision because of the same name. For example, java.sql.Date and java.util.Date - two Date classes can exist and be used because they're in different packages. It might help to envision packages and their sub-packages as a hierarchy of folders.
Imports are a convenience feature that lets you reference classes by their simple name (Math or String) instead of their fully qualified name (FQN) (java.lang.Math or java.lang.String) every single time you want to use it, which gets painful and clutters up your code, making it much less readable.
Imports don't add anything to your code or make it less efficient since the imported packages aren't linked to your code or anything like that - as mentioned above, it's simply a way to avoid having to use the FQN all the time.
So to answer your question, no, the import is not necessary but then you'd have to use org.apache.commons.lang.StringUtils every single time instead of just being able to use StringUtils. So while not necessary, it's usually convenient both for yourself and anyone else who's going to try to read your code.
You are trying to use these methods on Strings, you should read the documentation of the library you want to use.
Because in documentation you have:
static int indexOfAny(String str, char[] searchChars)
static == you should call this method like this: StringUtils.indexOfAny(...)
String str == put your string here
char[] searchChars == put array of chars which you're searching
Search a String to find the first
index of any character in the given
set of characters.
I have two classes in my Java project that are not 'related' to each other (one inherits from Thread, and one is a custom object. However, they both need to use the same function, which takes two String arguments and does soem file writing stuff. Where do I best put this function? Code duplication is ugly, but I also wouldn't want to create a whole new class just for this one function.
I have the feeling I am missing a very obvious way to do this here, but I can't think of an easy way.
[a function], which takes two String arguments and does soem file writing stuff
As others have suggested, you can place that function in a separate class, which both your existing classes could then access. Others have suggested calling the class Utility or something similar. I recommend not naming the class in that manner. My objections are twofold.
One would expect that all the code in your program was useful. That is, it had utility, so such a name conveys no information about the class.
It might be argued that Utility is a suitable name because the class is utilized by others. But in that case the name describes how the class is used, not what it does. Classes should be named by what they do, rather than how they are used, because how they are used can change without what they do changing. Consider that Java has a string class, which can be used to hold a name, a description or a text fragment. The class does things with a "string of characters"; it might or might not be used for a name, so string was a good name for it, but name was not.
So I'd suggest a different name for that class. Something that describes the kind of manipulation it does to the file, or describes the format of the file.
Create a Utility class and put all common utility methods in it.
Sounds like an ideal candidate for a FileUtils class that only has static functions. Take a look at SwingUtilities to see what I'm talking about.
You could make the function static in just one of the classes and then reference the static method in the other, assuming there aren't variables being used that require the object to have been instantiated already.
Alternatively, create another class to store all your static methods like that.
To answer the first part of your question - To the best of my knowledge it is impossible to have a function standalone in java; ergo - the function must go into a class.
The second part is more fun - A utility class is a good idea. A better idea may be to expand on what KitsuneYMG wrote; Let your class take responsibility for it's own reading/writing. Then delegate the read/write operation to the utility class. This allows your read/write to be manipulated independently of the rest of the file operations.
Just my 2c (+:
I'm writing a functionality where it would be helpful to get the classes inside a certain package of my program. Also, I only want the classes that subclass a certain class.
I need the classes in order to call static methods on them.
Is there an automatic way to do this? If so, is it slow?
In case I was not clear, what I want is something like this:
ArrayList<Class<? extends MySuperClass>> classes = ;
classes.add(MyClass.class);
classes.add(MyClass2.class);
Instead of having to call add for each class, I would like to automatically get that class list.
The number of classes is small, so I would not mind declaring them manually if the automatic trick would be slow - this app is for a mobile platform.
In either way, I would also like to know how to call the static method for each method in the ArrayList:
// error The method nameOfStaticMethod is undefined for the type Class<capture#2-of ? extends MySuperClass>
classes.get(0).nameOfStaticMethod ();
Thanks for your comments.
Java doesn't provide this ability. There is no introspection at the package level. The classes could be records in a database, or on the other side of a network connection. There's no requirement for them to be stored and organized so as to facilitate enumerating them by package.
You could make a custom class loader and API to provide a method of listing the class names.
I too would like to list all classes in a package but so far the methods of doing this is pretty bad:
Like JOTN suggested - needs file access - not if it is a jar
Listing a JAR entries - well, also needs the jar file
Quoting a older SO question:
It isn't possible to query a Package for it's Classes (or even its subpackages). http://forums.sun.com/thread.jspa?threadID=341935&start=0&tstart=0 contains a very good discussion about why this is problematic, as well as a handful of solutions to your problem.
Anyways, here is how you invoke static methods on the class:
Method m = Integer.class.getMethod("toString", Integer.TYPE);
System.out.println(m.invoke(null, 123));