Analyzing Java code across Eclipse projects - java

We want to use Rascal to find all unused public methods in a collection of Java projects in an Eclipse workspace. I have just learned how to create a model of a Java project in Eclipse using createM3FromEclipseProject and navigate that. But this takes only one project into account. How do I perform this analysis across all Java projects in my workspace?

Excellent question. You extract the models from each project, given the right Eclipse compiler settings and everything, then you can merge the models to get an overarching model:
import lang::java::m3::Core;
M3 composeJavaM3(loc id, set[M3] models) // the function to call
This will allow you to do a cross project analysis on the resulting M3 model.
There are some caveats, namely if the same qualified class name exists in both projects but they are in fact different classes then the compose function will map them onto each other. To fix such issues you would first have to do some preprocessing (see the link function), but we have yet to get experience in that.

If you are comfortable programming in Rascal, you could do the following:
Create a java function in rascal that gets the set of projects in the workspace as a set of locations. The locations need to be in the |project://project_name| format and the projects need to be accessible.
Create a rascal function that iterates over the set, creating the models using createM3FromEclipseProject and then composing them using composeJavaM3 into a single model to perform the analysis on.
If not, you can create an issue here and we could add it to an unstable build. This hasn't been added because of the caveats mentioned below.

Related

Loading Java class files for Soot dynamically in Eclipse

I am currently working on a program which compares two control - flow graphs with each other(the graphs are generated with Soot). These graphs belong to two different classes; so one cfg for each.
Currently I am using the following to load classes:
SootClass sClassNew = Scene.v().loadClassAndSupport("Calc");
sClassNew.setApplicationClass();
SootClass sClassOld = Scene.v().loadClassAndSupport("Calc2");
sClassOld.setApplicationClass()
This works if I add a folder with classes Calc.java and Calc2.java by right-clicking on the project | Java Build Path | Add External Class folder| choose the folder.
Unfortunately this is not exactly what I want since:
The two classes will have the same name since they are different versions of each other. In other words, one class is an updated version of the other.
When the program is executed, I want to make the user capable of choosing the files so that a cfg is built. Therefore, I must eliminate the above steps so as to add the classes and need a way to add them at run-time.
An important note is that Soot will only load files from JAR files and directories found on Soot's classpath.
Does anyone have an idea how I can solve problems these two problems please?
Soot is not really set up to deal with this. It's main data structure is the Scene, in which it holds all classes it reasons about and the scene can only hold exactly one class instance per class name - there can be no two different versions.
Having said that, we have recently built an extension to Soot called Reviser (currently under submission): https://github.com/StevenArzt/reviser
Reviser incrementally updates a program's inter-procedural control flow graph and the induced IFDS/IDE analysis information. To make this work, we had to poke around with Soot's class-loading mechanism quite a bit, though; this is far from trivial. If you are interested in the details please send a personal mail to Steven Arzt and myself.

How to manage same java code in different package with git?

I'd like to do some versioning of some Android code.
I pushed the code (only the res and src directories) and now I want to pull it in some other package.
How can I manage that, given that the code in my git repository has it's source in src/com/some/package/ and I want to clone it and get the source in src/some/other/package/?
I'm aware of this question, but I can't see any answer that helps.
What you can do as an alternative to directly managing it with git, is to separate the common code into its own Android Library Project. Then you would be able to add that library to the other two projects, giving you access to the same code base.
This would have you end up with three projects, and three repositories. Two of each for the separate projects, and one of each for the library project.
One thing to be aware of, however, is that if there is specific code for one project inside of the library, it will also affect the other project. Some of this could be handled by subclassing and overriding methods/properties as needed. Another way around this, as suggested by jul, would be to have branches for each project.
A nice benefit of doing it this way is that if you make a bug fix in the library that you found while working on one project, you'll be able to get that in the other for practically free.

Why shouldn't we use the (default)src package?

I recently started using Eclipse IDE and have read at a number of places that one shouldn't use the default(src) package and create new packages.
I just wanted to know the reason behind this.
Using the default package may create namespace collisions. Imagine you're creating a library which contains a MyClass class. Someone uses your library in his project and also has a MyClass class in his default package. What should the compiler do? Package in Java is actually a namespace which fully identifies your project. So it's important to not use the default package in the real world projects.
Originally, it was intended as a means to ensure there were no clashes between different pieces of Java code.
Because Java was meant to be run anywhere, and over the net (meaning it might pick up bits from Sun, IBM or even Joe Bloggs and the Dodgy Software Company Pty Ltd), the fact that I owned paxdiablo.com (I don't actually but let's pretend I do for the sake of this answer) meant that it would be safe to call all my code com.paxdiablo.blah.blah.blah and that wouldn't interfere with anyone else, unless they were mentally deficient in some way and used my namespace :-)
From chapter 7, "Packages", of the Java Language Spec:
Programs are organized as sets of packages. Each package has its own set of names for types, which helps to prevent name conflicts.
I actually usually start by using the default package and only move it into a real package (something fairly easy to do with the Eclipse IDE) if it survives long enough to be released to the wild.
Java uses the package as a way to differentiate between classes. By using packages, you can have an org.example.Something class and an org.example.extended.Something class and be able to differentiate between them even though they are both named Something. Since their packages are different, you can use them both in the same project.
By declaring a package you define your own namespace (for classes). This way if you have two identical classes using a different package name (namespace) will differentiate between which one you want to use.
The main reasons I can think of are:
It keeps things organised, which will help you (and others!) know where to look for classes/functionality.
You can define classes with the same name if they are in different packages.
Classes/etc in the default package cannot be imported into named packages. This means that in order to use your classes, other people will have to put all their classes in the default package too. This exacerbates the problems which reasons 1 & 2 solve.
From a java point of view, there are two general dev/deploy lifecycles you can folllow, either using ant to build and deploy, or the maven lifecycle. Both of these lifecycles look for source code and resources in local directories, and in the case of maven, in defined repositories, either locally or on the net.
The point is, when you set up a project, for development and eventually deployment, you want to build a project structure that is portable, and not dependent on the IDE, ie. your project can be built and deployed using either of your build environments. If you use a heavy dependence on the Eclipse framework for providing class variables, compile paths, etc.. you may run into the problem that your project will only build and deploy using that configurationj, and it may not be portable to another developers environment, so to speak.

Java package / class library convention?

I am a C# developer and I am messing around with Java. In C# I would normally have my front end project and then when I need to add another layer to the project (i.e service layer etc) I would add a class library in the solution and add a reference to it.
What is the convention in Java? Do you add another Java project to the workspace and then reference the project? Or do you add a package to the project which contains your front end?
UPDATE
Sorry, I am using eclipse...hence the reference to 'workspace'
There's no real convention. When you say "workspace" you're not referring to Java, but rather a development environment (sounds like Eclipse). There are a number of ways to do it; you could do it the way you're suggesting, you could include the dependency via Maven, you could combine them all together in one project, etc.
Which to choose depends on your needs, who else will be consuming either the individual libraries or the completed project, and so on.
How to divide your source code depends a lot on the structure of your project. It is important to pay attention to a good code organization. You should keep classes for a common task or for a distinct application layer in own packages. You should watch for inter-package dependencies.
Using different "projects" (be it Maven or Eclipse projects) helps ensuring that you (your developers) do not violate structural boundaries because the compiler checks the dependencies (one project references the other project, like in C#/VS). Maven generates a build artifact (e.g. a JAR file) for every project.
To summarize, I think it is a good idea to create new individual projects for each program module in order to be able to manage the dependencies between the projects explicitly.
You are assuming everyone works with eclipse, it seems (your references to "workspace").
You can do anything you want, but keep in mind others might not be able to include 'separate' projects for various components of the application.
You can easily address that issue by using some build tool (ant, maven) to build appropriate jars for the various app components, like data-model, persistence, API, etc.
If you front-end is an RIA, might make more sense to develop it as a separate project, although not necessary. If your app is some sort of Java driven UI, you can still do whatever you want, in both cases make sure the UI components have their own package hierarchy.
Yes, I guess I would create a separate package. So your UI code might be in com.mycompany.app.ui, your service code in com.mycompany.app.service, etc. However you want to organize your classes is up to you. Java itself doesn't care what packages the classes are in. The packages just help to make the code more manageable for the developers.
Unlike most things in Java, there's no real convention defined for how to split up project.
In my experience, it makes sense to include code that serves a particular business purpose in a single project, and to separate out code that you intend to share between multiple projects, or code that is not specific to a particular business purpose (e.g. database access, JMS libraries, etc.), into a separate project.
If the UI and the server layer are being developed in a single project, which means packaged and deployed in the same WAR file, I'd create a new package for the service and add classes and interfaces as needed.
If the service layer is deployed separately, I'd add dependencies as a JAR to the web project. All I should need are clients for the service.
If you're working in Eclipse follow these steps:
1) Right-click the project and choose "Build Path"-"Configure Build Path..."
2) Switch to Libraries tab and click Add External JARs (or just Add JARs if they're already in the workspace).
3) Now you can either manually add import of the corresponding class, or just hit Ctrl+Shift+O (Source-Organize Imports) and Eclipse will do the job for you.
I suggest you can use netbeans then you can create a java class library,when you deploy your project,netbeans will generate jar files for you,and place them at the right location.I'm also a ms developer,hope it helps

How to determine which source files are required for an Eclipse run configuration

When writing code in an Eclipse project, I'm usually quite messy and undisciplined in how I create and organize my classes, at least in the early hacky and experimental stages. In particular, I create more than one class with a main method for testing different ideas that share most of the same classes.
If I come up with something like a useful app, I can export it to a runnable jar so I can share it with friends. But this simply packs up the whole project, which can become several megabytes big if I'm relying on large library such as httpclient.
Also, if I decide to refactor my lump of code into several projects once I work out what works, and I can't remember which source files are used in a particular run configuration, all I can do it copy the main class to a new project and then keep copying missing types till the new project compiles.
Is there a way in Eclipse to determine which classes are actually used in a particular run configuration?
EDIT: Here's an example. Say I'm experimenting with web scraping, and so far I've tried to scrape the search-result pages of both youtube.com and wrzuta.pl. I have a bunch of classes that implement scraping in general, a few that are specific to each of youtube and wrzuta. On top of this I have a basic gui common to both scrapers, but a few wrzuta- and youtube-specific buttons and options.
The WrzutaGuiMain and YoutubeGuiMain classes each contain a main method to configure and show the gui for each respective website. Can Eclipse look at each of these to determine which types are referenced?
Take a look at ProGuard, it is a "java shrinker, optimizer, obfuscator, and preverifier". I think you'll mainly be interested in the first capability for this problem.
Yes it's not technically part of Eclipse, as you requested, but it can be run from an Ant script, which can be pretty easily run in Eclipse.
I create more than one class with a main method for testing different ideas that share most of the same classes.
It's better to be pedantic than lazy, it saves you time when coding :-)
You can have one class with a main method that accepts a command-line argument and calls a certain branch of functionality based on its value.

Categories