Creating a java library - java

This may be a silly question, but right now I have a rather large class that I want to use as a library. Where somebody can simply add this jar file to their classpath. And then simply do an import statement at the top, then he or she can start using this class.
Is there anything special I need to do or can I simply just use the jar file built?

a rather large class
Large classes don't usually make good libraries :)
Technically, yeah, all you need it put it in a JAR. To make it easy to use (including by yourself), you should spend some time to refactor it and break up the functionality into smaller classes according to the Single Responsibility Principle. For static utility methods, consider whether you can group them into several classes according to some theme, or perhaps even turn some of them into non-static methods (if there are situations where a client would use more than one of those methods on the same data, they're begging to become instance methods).
And you definitely should write Javadoc comments for all public classes and methods, and publish the Javadocs along with the code. A library without an API doc is almost useless.

You can simply put the JAR into the classpath and can import the class. No more magic needed.

You should just be able to use the jar, as is. All you need to ensure is that the class files in the JAR are in the correct directory structure (according to their package names)
Class Foo in package bar -> bar/Foo.class in the jar

create a JAR of .class files of your "large class" and then put that JAR in your CLASSPATH.
Then you should be able to import the classes in the JAR via "import" statements.
If you anticipate too many huge classes/libraries, check out the JVM parameters -Xms and -Xmx that takes care of heap usage.

Related

Some problems about adding external library in IntellijIdea

I have added an external library.
But I can only use it in src.I cannot use stdlib.jar(the external library) in com.jc.Searching. How to fix it?
detailed information:
According to your answer on my comment above. Usually, you need to provide an import statement in your ST class, which belong to com.ja.Searching package. Here you can read about it.
In your case, you can't do it, because a StdOut class is probably declared in default package within your external library and it's not possible in Java to import classes from unnamed package. Only way to get this class instance, is to try to use reflection, but obviously, that's not the way you need and even have to do.
It seems to me, you are using some lib, which doesn't provide any packages and all it's classes belong to the default one, that is why you don't need to make an import in your class within default package. It's not a good practice at all, but sometimes used in some tutorials to make a code snippets be more readable.
Classes in the default package can't be imported. So they can effectively be only used by classes in the default package as well.
It's a really, really bad practice to put classes in the default package, especially for a reusable library. Ask the author of the library to fix it, and use a proper package name.

Java: Packaging classes with cross-module-usage

In my project (a parser for various formats), I packaged the modules by functionality but there are a few classes which are needed by every module.
Now I'm not sure what's the best practice here:
Should every module/package have a duplicate of the class? The compiler will probably optimize this anyway, won't it?
Create a "Shared" package? This doesn't feel right...
Other options?
I wouldn't package duplicates of the class, that could cause you some endless headaches, because the same class file contents loaded by different classloaders is not considered to be the same class at all by Java, so you'll get impossible to understand error messages. And if all your jars are in the same class loader, only the first class will be loaded, so you may as well put it in one place only.
I would certainly package utility classes in their own jar and have a dependency from all the other packages, as is the case with other libraries you may use etc. You can even use the classpath attribute of the manifest to reference the library easily.
I would suggest you create an abstract class and provide implentation separately in each class and package them separately.

What's the point of using .class objects?

In the past few weeks, I've run into several different peoples' code using .class objects. For example, ArrayList of classes : ArrayList<Class> but how to force those classes to extend some super class?.
I looked them up: http://docs.oracle.com/javase/tutorial/reflect/class/index.html
I'm just wondering why you'd want to use .class objects. I can see getDeclaredFields() and getDeclaredMethods() being potentially useful, but I can't really think of concrete examples as to why I'd actually want to use the .class objects in lieu of something else. Could anyone shed some light on this topic?
Thanks in advance.
I think you misunderstood the concept. Class class has nothing to do with compiled classes (.class).
Class is a class that represents a Java class internal structure, such as fields, methods, etc... This is a compile-time entity, which you can use in your code (even before compiling).
.class is a compiled Java class file, which is Java bytecode. This is not a "code" entity (you cannot use it as a class or object in your code -besides as any file-) and it is not available before compilation.
Reflection (Class is part of the reflection package) is useful when you want to do advanced stuff with the code, like manipulating it, accessing its members, getting information from it, etc...
A typical example where you want to use reflection is making a Java debugger. Since any code can be run on the debugger, you need reflection to get information about the object instances and their structure and show this to the user.
Reflection is one reason to use it. Another good example is dynamically constructing objects at runtime.
For example, the Spring framework uses configuration files that contain the names of Java classes. Somewhere in that code, Spring needs to build object instances of those classes. In this way, the objects are created without the compiler needing to know anything about the Java classes at compile time.
This can be useful when developing an interpreter of a scripting language running on JVM, which has an ability to call Java methods.
Also, might be useful in a system allowing for plugin extensions.
Another use case:
InputStream is = MyClass.class.getResourceAsStream("/some/resource/in/the/jar");
Plug-in are a big use for this.
Dynamically load .class files which are in say, your plugins folder and execute some specified function from said files. Then, you can have 0 or more plug-ins and any combination of them installed for your application at a time.

Retrieving a list of classes from a package in an Android project

I'm aware that it isn't easily feasible to get all of the classes in a package using reflection, but I'm wondering if someone knows of a good solution/workaround, specifically for an Android project?
Given a package, I need to be able to retrieve all of the classes from it and process annotations from them using reflection.
Does anyone know of a way to do this? Are there any libraries available?
Scanning the filesystem as most solutions for non-Android Java do won't help on Android. Here's a (theoretical) solution that is android-specific: http://mindtherobot.com/blog/737/android-hacks-scan-android-classpath/
However, it remains a hack, since Java unfortunately does not directly support this.
Existing dependency injection solutions use reflection for processing the annotations, but still need the resources to be declared. See this example of DI using reflection.
If you are using Ant to build your artifacts, you could read the contents of your source directory using Bash or Java, and use this to regenerate the full hierarchy of classes automatically during each build. This might make things tricky if you rely on heavily on the Eclipse IDE though, since the list might be out of date until you run another Ant build. (Note: according to Pyscho you can make Eclipse use Ant by altering the project configuration, see comments)
Another option might be to process the AndroidManifest file using the AssetManager, but you would be limited to the resources declared in that file. The compiled classes themselves are in-lined and optimised in the classes.dex file, and as such you're unlikely to get much useful information from it.
I think you might find the answer here https://stackoverflow.com/a/1457971/1199538
there is a java file attached so you can download it and try it
short snippet from the answer following:
This method can only be used when:
You have a class that is in the same package you want to discover, This class is called a
SeedClass. For example, if you want to list all classes in 'java.io', the seed class may be java.io.File.
Your classes are in a directory or in a JAR file it has source file information (not source code file, but just source file). As far as I've tried, it work almost 100% except the JVM class (those classes come with the JVM).
Your program must have permission to access ProtectionDomain of those classes. If your program is loaded locally, there should be no problem.
You can do classpath scanning for Android at compiletime, before the JVM bytecodes have been converted to Dalvik bytecodes, e.g. using the ClassGraph library (I am the author):
https://github.com/classgraph/classgraph/wiki/Build-Time-Scanning

Organize small utilities functions

After years of programming, we all have a set of small functions used as helpers utilities that we wish it comes build-in so we can use it in any project and have ti taken care by more people (test and optimized).
I have quite a collection of these functions. I wonder how do you guys organize them? Do you have any tips?
This is how I do it. I put it in a separate project (an eclipse project) let say "MyUtils" and it referred to by other projects. This works but because the utils collection are getting bigger and bigger something it is kind of weird that the utils are bigger than the project code (for small projects). And to ship it in Jar, you have to select them all by hand (or include them all). Is there a better way?
Also, as Java requires all functions to be in a class so I have ton of static functions (those that does not fit in OOP) for example a function read text file from a file name. Like this:
package nawaman.myutil;
public class UText {
static public String ReadTextFile(String pFileName) {
...
}
static public String[] ReadLines_fromFile(String pFileName) {
...
}
static public String ReadLine_fromFile(String pFileName, int pLineNumber) {
...
}
...
}
So when I need to include all the functions goes when though it is not used.
Is there a better way to do this?
I use eclipse on Linux anyway if there is special technique for it but fell free to share if you have techniques with other tools.
I treat such utility classes just like other components external to the software that I develop:
For each component I create a Eclipse project and build it to a jar.
Classes are grouped logically in packages, e.g. [domain].util.net, [domain].util.text etc.
In a project I include the dependencies I need. Maven can help you here.
You write that utility classes have a lot of static methods. That's something I don't use a lot. For example the text functions you show can be refactored to a class or set of classes that extend or implement classes and interfaces from the collections framework. That makes it easier to integrate my code with other libraries.
This works but because the utils collection are getting bigger and bigger something it is kind of weird that the utils are bigger than the project code (for small projects). And to ship it in Jar, you have to select them all by hand (or include them all). Is there a better way?
For my projects I use javac to select all the classes from my util libraries. For this I compile all classes from my project to an empty output directory. javac automatically resolves the dependencies to the util libraries because I added the util library pathes as source pathes. Now I can create a jar that contains all classes of my project and only the needed classes of the util libraries.
Also, as Java requires all functions to be in a class so I have ton of static functions (those that does not fit in OOP) for example a function read text file from a file name.
I do it the same way. But I try have a lot of small util classes instead of a few big ones, so that I don't have to include tons of unneeded methods to my jars.
My "utilities" have their own package namespace and SVN repository. They are, in essence my own libraries: distinct projects which may be pulled in, shared, tagged, updated, whatever.
The organization used within each of these "libraries" depends on the scope and function in question.
Because I disagree with the structure being a slave to some potential class/JAR output:
If you are concerned about "method bloat" in the classes and/or JARs, please use an automated tool to combat this. ProGuards is just one example and, while it can obfuscate, it can work equally well at just "dead code elimination".
Split your utils module into smaller subprojects. Use Maven or other build system to track versions of all your util modules. They are crucial to your systems because I think they used are in almost all your projects. Use tools like Findbugs or PMD to mesure quality of your code.
Every project need to know which version of utils module is using. It unacceptable in my opinion to add to binaries/sources of one of yours 'nonutils' project some loosely coupled util classes.
Please, revise yours classes with other commons projects like Apache Commons. I assume that lot of your utility code is similiar. Think better of rewriting yours static metods, because they obstruct testing (I'm sure that Findbugs will be complaining a lot too).
To sum up - creating a utils library is a hard stuff and a lot of responsability. So requirements in area of code quality are very high. I hope that my advice will help.
You should be very careful with removing classes after compilation - you may end up in a class not found situation at runtime. If you never use reflection or Class.forName() you should be safe, but those introduce runtime dependencies which the compiler cannot help you with (like it can with "new").
Remember - those classes not used do not use memory in the running program, only uses bytes on disk.
Personally I've ended up at saying disk space is cheap, and the risk of accidntially removing a class defintion used causing a runtime break, is not worth it to me, so I say - all code used for compilation must be shipped.
I don't use Eclipse, but in Visual Studio you can add a reference to file without it being physically moved or copied. This allows you to define a file in the root of your source control that all of your projects can reference without it being included in every project or having to deal with the copying problem. With this kind of solution you can intelligently split your util methods into different files and selectively include them based on what individual projects need. Also you can get rid of the extra .jar.
That said, I have no idea if Eclipse supports this kind of file referencing, but it might be worthwhile to look.

Categories