1

Would it be possible to write Eclipse plugin, that:

  1. Whenever in our code we use ClassA.staticMethod1(); (ClassA come from included external jar)

  2. Plugin creates ClassA in our project.

  3. It copies that one used method only (and all needed imports and dependent methods) from jar to newly created ClassA - Unneeded class methods aren't copied to project and are still in external jar.

  4. When jar is removed all works fine.

What is your solution to achieve this?

thanks in advance



EDIT to clarify for @Thorbjørn Ravn Andersen:

given class is in a jar:

package com.ext.jar;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Utilities {

    public static Object giveFirstThing(){
        // some random method content to show what has to be removed and what has to stay
        List list = new ArrayList();    
        Object o = doThis();
        return null;        
    }   

    public static Object giveSecondThing(){
        List list = new LinkedList();       
        Object o = doThat();
        return null;        
    }       
    private static Object doThis(){
        Map<Integer, String> myMap = new HashMap<Integer, String>();
        return null;        
    }
    private static Object doThat(String ... param){
        Set set;
        return null;        
    }       
}

This class (in sources project), that uses only part (in this case 1 method, which uses other method) of that jar's class:

package com.foo.bar;

import com.ext.jar.Utilities;

public class Runner {

    public static void main(String[] args) {

        Utilities.giveFirstThing();

    }
}

The result is: class from jar is recreated in my project, as a normal compilable class, without methods and Imports, that I didn't need (so jar can be safety removed from project):

package com.ext.jar;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Utilities {

    public static Object giveFirstThing(){
        // some random method content to show what has to be removed and what has to stay
        List list = new ArrayList();    
        Object o = doThis();
        return null;        
    }   

    private static Object doThis(){
        Map<Integer, String> myMap = new HashMap<Integer, String>();
        return null;        
    }

}

SUM UP:

2 (of 4 total) method where needed, so they are copied.

4 (of 6 total) imports where needed, so they are copied too.

rest of class is ATM useless, so everything else is not copied.

EDIT2: I've added bounty, as a sign that I wish to find solution to this problem, which I believe could be useful open-source project. :)

12
  • 1
    You need an automatic stub generator? Commented Jan 13, 2012 at 14:46
  • @Thorbjørn Ravn Andersen, I need to copy code from jar, but only as much, as is needed to compile and work. I don't want to include that jar to final build. Commented Jan 13, 2012 at 14:48
  • I know some tools are out there to accomplish that task (I forgot their names). Nevertheless, this is a tough excercise, e.g.: what if your static method dymanically builds a classname and loads the class via reflection? Commented Jan 13, 2012 at 16:50
  • e.g.: jarg.sourceforge.net Commented Jan 13, 2012 at 16:51
  • 1
    @Thorbjørn Ravn Andersen, try now Commented Jan 13, 2012 at 17:32

1 Answer 1

1
+50

Although I am sure you probably could write an Eclipse plugin to do what you require, it sounds like a lot of work that you don't need to do.

I think the plugin you describe is essentially trying to achieve two things:

  1. Reduce the overall size of that library thus, reducing the overall size of your application.
  2. The ability to not require linking to a external library

The idea of essentially reducing an external jar library to only the core functionality you require is basically one role that obfuscation is used for. Many open-source obfuscation tools are available for Java the most popular probably being Proguard. Proguard is highly configurable and useful tool that can be used to remove shrink code, optimize and then obfusticate it.

The shrinking of current code from an obfuscation tool would fulfil the first goal that I think you are trying to achieve.

On top of that obfuscation tools would achieve much better results than the techique described by the plugin. See some results of Proguard here.

The second goal that you are trying to achieve seems a little odd. There is also nothing wrong with using external libraries. From a development point of view you want to know what your application dependencies are.

Dependencies on libraries in large projects need to be assessed (for things like risk etc.) and ultimately need to be managed. The idea of editing the library by removing the parts that you don't require might put you in danger of breaking licenses. It would also be an absolute nightmare if the original library is lost and all that existed was the created classes.

It would be much easier to state what your application depends and use a library dependency tool. Apache Ivy is a tool which does this and ultimately helps others who you collaborate with, by showing what your application depends and giving them quick an easy ways to get those libraries.

These types of tools tend to be used in larger projects where there are numerous dependencies and specific versions that must be used. For small projects you will mostly find they state that it requires only one or two libraries within the projects readme or build instructions.

Sign up to request clarification or add additional context in comments.

5 Comments

As my intentions aren't clear to you, maybe it would be easier if I tell you why I need such a tool. In our company we have some Utility classes (in jar*), that belongs only to us. If we do something for client, that may be done with help of this classes, we use them. Key point is, that only needed methods must be provided to client, only as much as is needed to compile. We do so by copy-paste copy-paste copy-paste and organize imports. I want to make this automatic. You used some of those methods - class is made outside of jar*, inside of project. And build team doesn't need jar*
So i asumed that some eclipse-plugin, used by random developers would be best and easist to use tool.
Yep, the easiest way to do this is to use Proguard. You will need to play around with the options (e.g. look at -keep -dontoptimize -dontobfuscate -verbose) but it will shrink all unused code away. I would extract the jar library to just it class files, write your code, run proguard, check the output and that everything worked then use javac. If you are really bothered about giving something to clients you should consider running Proguards to fully obfusticate your application. It can do an extremely good job of making your code difficult to work with if they extract a binary version.
If you want to automate the process use the ant tasks. proguard.sourceforge.net/#manual/ant.html
"Do you distribute the source code to the client?" - yes, so there's no point to make it obfusticated. Anyway thanks for your help. I'll take a look on it in some free-time, but for now, I'll keep my question open.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.