hide some class file or package in jar file - java

How can I export a jar without some class or package which I don't want others to use,but which is needed in project,means I can't delete them.

This doesn't make a lot of sense.
If the classes are needed to compile the project, then there are likely to be static dependencies on them in other classes. (Otherwise ... you would be able to just delete it / them.)
But if there are static dependencies on those classes, then you won't be able to run the applications unless those classes are present in the JAR file. If you leave the classes out of the JAR to stop people using them (or whatever), your application will die on startup with "class not found" exceptions.
If you want to stop people using the classes directly, you could try the following:
Change the classes access to "package private". This doesn't make it impossible to use them, but it makes it more difficult.
Change your project so that the dependencies on the classes are entirely dynamic; e.g. via Class.forName(...) or dependency injection. Then you can exclude the classes from the JAR as required. But once again, if your application needs to use the classes, they have to be accessible at runtime (somehow), and it will therefore be possible (somehow) for other people to get hold of them.
Change your project to allow you remove the classes entirely. This is the only sure-fire solution.
Finally, before you go to all of this trouble you should ask yourself why you are even bothering to do this. Why don't you just let people use the classes anyway? What is to stop them getting the classes from somewhere else ... or implementing their own versions from scratch?

If the class is needed for your program to work, you can't omit it from the JAR.
You can put classes in a package that has something like "internal" in its name — e.g. com.example.internal — to indicate that the classes aren't meant for others to use or rely on. It can't prevent anyone from using your class for their own purposes, but it at least indicates that they do so at their own risk, that your internal interfaces might change in future versions of the program, etc.

A simple way is to use the package private access modifier for classes. That will make it difficult for others to access the classes, but it will also affect your ability to use them from other packages.
A more advanced way would be to use OSGi and only publish those classes you want others to use. That will make it impossible for others to access the classes while not restricting your access to them.

Put them into a separate jar file, include that jar file (as a single file, maybe with a nondescript name) into your jar file, create a custom class loader to open that embedded jar file from your code, bootstrap an entry point with reflection (because you cannot have static dependencies on it) into that new class loader .
Or just accept the fact that since the code is in there somewhere, any amount of obfuscation is just an inconvenience to everyone and cannot really hide anything.

Related

Is there a way to unpack jars in runtime and access methods of classes?

This might be a little vague but I wanted to know if I have a class name (including the package) before hand, say in a file and I have a bunch of jars in the classpaths. Then is there a way I can look into a particular jar to find that class and access some method from that class?
What I am actually trying to do is to load some values from different class, dynamically. If the above approach is flawed then is there any other way to do it? Am not completely certain about how the class loader works, so I didn't want to go down that rabbit hole just yet.
EDIT An abstract example of what am trying to do:
I have a program that builds a graph for me using certain information, for the purpose of this example lets say that information is alphabets. I have some jars in my classpath that have a class that has a method that returns these alphabets for that specific class. Now I got the order of the classes I need to build the graph from, so if I am able to extract these alphabets from the jars, I can build my graph.
You can use a URLClassLoader and its methods to find classes in a .jar file (typically) once you have the Class object, you can use java.lang.reflect to instantiate objects, call methods, or inspect variables
If the jars are your own: Consider using java.util.ServiceLoader. It helps to find any classes residing on the classpath at runtime that implement a given Interface, as long as you declare them in a META-INF/services list.
So you let the classloader load the classes without knowing their names and simply call their methods.
I'm not sure if there is a clean way to find out (enumerate) the names of all classes only by reflection without scanning the jars as a zip.

Compile plugin code in Java without parent class body

I´m trying to add a plugin system to my app. I have an abstract class that plugins must extend. This class provide usuful methods so I really need it. The problem is that these plugins could be written by anyone so I suppouse that they'll need the abstract class code to be able to compile their code.
I don´t want to complicate the process of creating a plugin. Is there a way to compile the code without know the abstract class body (only its methods)?
Thanks in advance.
Is there a way to compile the code without know the abstract class body (only its methods)?
No. In order to to compile a class declared as
class A extends B
you'll have to have B in source format in the source path or in .class format on the class path.
(If knowing only the methods is sufficient for writing the plugin, it sounds more like you're after an interface than an abstract class.)
I don´t want to complicate the process of creating a plugin.
Providing the compiled .class file of B is completely uncomplicated and probably the best practice in this scenario.
Actually, having an API at hand through a .jar-file containing the relevant classes and interfaces is probably the standard.
To be clear:
Take the classes that are relevant for plugin-development, compile them, and put them in, say pluginapi.jar
Distribute the .jar and tell plugin developers that their plugins should compile, provided the pluginapi.jar
Ask the plugindevelopers to provide you with plugin.jar (not necessarily including pluginapi classes)
In your application, make sure that the plugin API classes are present, for instance by including them the class path.
Load the plugin classes.
You could ask your plugin authors to provide you some classes with some specified methods and invoke those using reflection. This would mean that they could write a plugin that can be compiled without access to any of your code.
But it would also severely limit their possibilities: How should the plugin interact with your system if they have no way of calling into it? Since the only sane way to provide that is to make some classes (or interfaces) accessible, you can just as well provide an interface (or abstract class) that they need to implement/extend.
You could put that interface (and all interfaces/classes visible to plugins) in a separate .jar file. This way they only need that jar file to compile a plugin.
You can just provide a jar file with all necessry java files. But remember, that once you publish the api, you should be very careful with changing it.
Alternatively you can go around by not forcing your users to extend a class or implement an interface but have them provide a function with a certain signature -- which then you can call via reflection. In this case they won't need anything from you, however, if they get the function wrong obviously you won't be able to call the plugin.
In these cases Java scripting can be very useful. Have your plugins written in Groovy and the codes can be easily (down)loaded and executed in your framework, something like this http://groovy.codehaus.org/Embedding+Groovy

Strategies for mixing in the gwt compatible and non compatible source

Yes i know one alternative to solving this problem is simply to create two source directories from the original. The class path for the GWT compiler would thus be setup to simply only see the compatible source while both would be used for the server portion of your app.
Firstly i find this kind of ugly, because it means i now have two source directories with potential doubles of classes.
refactoring and other structural abilities of the IDE can potentially be problematic as it will get confused.
Sometimes its not possible to put some stuff in separate packages: think client and server packages simply because one would then have to make something public which should really be package private to limit scope accessibility.
is there a library that enables classes or methods to marked as ignored by the GWT compiler ?
Is there a better way ?
You can exclude classes (files actually) from GWT's source path using Ant-like includes/excludes: http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuidePathFiltering
You cannot exclude methods or inner classes though, it really is file-based. See http://code.google.com/p/google-web-toolkit/issues/detail?id=3769
Make a shared directory that has the code that both the GWT side and server side can read. Any classes that would be duplicated instead go into this folder, to be accessed (without duplication!) from both client- and server-sides of your app.

How to create my own java library(API)?

I created a program in Java and I designed it so that methods that I want them to appear (getter methods) in the main, I can call them easily after initiate the class that holds these methods.
The question is that, I need to make this application (that holds the getter methods) to be like an API so that I can give my application for developers to use my functions (the getter methods) if they need them, and only what they need is to add this file (I think the API after is done shown as .jar file).
How can I make it so that I can make my code reusable with other application? It's similar to the .dll, I think.
Thanks a lot ;)
Create a JAR. Then include the JAR. Any classes in that JAR will be available. Just make sure you protect your code if you are giving out an API. Don't expose any methods / properties to the end user that shouldn't be used.
Edit: In response to your comment, make sure you don't include the source when you package the JAR. Only include the class files. That's the best you can really do.
To be useable as an API, your classes should:
Use a unique package (ideally following the convention, i.e. the reverse of a domain you own as prefix). This prevents naming conflicts
Have only those classes and methods public or protected that are intended to be used by others. This makes it easier to use.
Have extensive Javadoc comments.
Be available as a JAR file - ideally separate JARs for binary distribution, source code and javadoc files.
You need to package your application as a jar file. You can use ant jar task to create jar files or you can use the jar command.
For ant tasks look at this link.
For creating it manually look at this link.
Make sure you write and publish javadocs for all your public and protected classes and methods.
To create the jar:
jar cf <jar_name> <sources>
There are several ways you can expose your code. Creating a jar and distributing that may be the easiest as other developers will just have to include your jar. However, if you are talking about "anyone" accessing your code, a web service may make more sense as you can provide access to the data without providing all of the necessary code. You mention providing access to your getters - if you just create a class that has getters, the other developers can use them, but how are they going to be populated? If your application is self contained in that it gets the necessary data and provides the getters, that should work, but if you are talking about providing access to data from your running application, a web service makes more sense as your application can retrieve the data and provide access via publicly accessible methods.
You most likely want to create interfaces as well so developers can code against the interface and you can change the internal workings without impacting them. Any API that will be used by others should be extensively documented as well.
Well, depends on your IDE. I use Netbeans, so I just hit build project, and viola! A jar file is created in my directory specified. Now, that's just for compiling. All anyone has to do is download your .jar file, and if in Netbeans, right click libraries, add jar/folder, and select the downloaded file.
You can also consider:
Include some samples that demonstrate how to use your library
Build your jar using Apache Maven
Put your jar in a public maven repository
Publish a new version of your library as you find/fix bugs
If you want to hide your implementation, you can pack your jar with obfuscation, so that if someone decompiles your classes, the code will be difficult to read

Can classes of same package spread across multiple Jar files?

I am using some classes from a JAR file and they belong to a package (com.abc.xyz).
The class am writing also belongs to that package but I won't be able to bundle my file into that JAR file. Is it possible to have classes that belong to the same package spread across multiple JAR files?
By default, absolutely.
However, if you want to make sure that classes from a particular package are only loaded from one jar file, you can add that information to the manifest.
It is quite doable unless the JAR has sealed the package.
I don't see why it wouldn't be possible. All that matters is that the classes are in the classpath.
It's probably not something that you should want to do. If it's in the same package, should it not be packaged together (I believe Jigsaw intends to allow splitting packages between modules, but that's a different kettle of fish).
It can be blocked if either package is marked sealed in the manifest. I would recommend marking whole jars as sealed as a matter of course.
It can also be blocked if there are different signers on the classes and the classes are loaded by the same class loader.
If you load classes using a different class loader, although the "namespace" will be the same, you won't actually get package (and relevant part of protected) access.
Sometimes you have to do that if you want to extend the functionality of third party libraries but they are not open sourcve and/or you don't have sources

Categories

Resources