Altering open source code - java

Assume that I am using an open source jar file in my project which is of size 11mb. But I am not utilizing this jar fully (I'll never utilize in the future too). I know that I just need couple of classes from this jar which does my job. In such case, can I just delete the other classes in the jar file and use it?
I'll make sure that whatever the classes remain in the jar is complete by itself. Meaning, these classes do not depend on any other classes in the jar. So Can I just remove the unwanted classes in the jar so that the jar file gets reduced? If I do this job, it it legal? Am I allowed to do such stuff and use in my project?

SmartGWT appears to use the LGPL licence. This means you can link to it even in a proprietary closed-source application without the need to release your source code if you distribute it.
However, this freedom may not apply if you modify the library.
A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License.
It could be argued that chopping out bits of the library creates a derivative work even though you've not altered the source code itself, but IANAL.
Of course, if you are not distributing your project (for example, it's an internal business application for your company) then I don't believe the requirement to release your source code applies even with a derivative work.

Related

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

package structure & directory structure

In Java web application, what is the exact meaning of the term "package structure" and "directory structure" ? Aren't they the same? I saw some articles have these two terms, but I am not sure about the exact meaning and difference.
Package is a collection of code that changes together, is used together and is shipped together. So a jar/war is a package.
Package Design Principles
I understand that you meant source package, which is more like directory structure. But I believe, a directory is a physical representation on hard drive.
EDIT: I had writtern original answer more than 3years back. But did not change as it was accepted. But changing it now so that any new visitor may benefit and also to avoid link rot. Some additional meaning of package may be extracted based on the discussion below. For example, is a jar a package?
Classes that get reused together should be packaged together so that the package can be treated as a sort of complete product available for you. And those which are reused together should be separated away from the ones those are not reused with. For example, your Logging utility classes are not necessarily used together with your file io classes. So package all logging them separately. But logging classes could be related to one another. So create a sort of complete product for logging, say, for the want of better name commons-logging package it in a (re)usable jar and another separate complete product for io utilities, again for the want of better name, say commons-io.jar. If you update say commons-io library to say support java nio, then you may not necessarily want to make any changes to the logging library. So separating them is better.
Now, let's say you wanted your logging utility classes to support structured logging for say some sort of log analysis by tools like splunk. Some clients of your logging utility may want to update to your newer version; some others may not. So when you release a new version, package all classes which are needed and reused together for migration. So some clients of your utility classes can safely delete your old commons-logging jar and move to commons-logging-new jar. Some other clients are still ok with older jar. However no clients are needed to have both these jars (new and old) just because you forced them to use some classes for older packaged jar.
Avoid cyclic dependencies. a depend on b; b on c; c on d; but d depends on a. The scenario is obviously deterring as it will be very difficult to define layers or modules, etc and you cannot vary them independly relative to each other.
Also, you could package your classes such that if a layer or module changes, other module or layers do not have to change necessarily. So, for example, if you decide to go from old MVC framework to a rest APIs upgrade, then only view and controller may need changes; your model does not.
In most Java applications, the package structure should be matched by the directory structure for the .java and .class files. However these directories are part of a larger directory structure, including other data than the source and/or the bytecode.
Depending on the context, the "package structure" might also refer to delivery packages, each containing an application or a library.

Changing dalvik/libcore causes rebuilding the whole framework

I'm adding some interception routines to Dalvik libcore methods (e.g. file open method in libcore/luni/src/main/java/org/apache/harmony/luni/platform/OSFileSystem.java), which I think only changes basic sharing libraries. But to my surprise, every time I run make after modifications, it rebuilds nearly everything of the framework, such as Calculator application, W3C DOM parser, etc. It really takes time to build the framework after a small modification. I'm wondering if it is possible to reduce number of rebuilt components after modifying dalvik libcore? Thanks.
It actually isn't too surprising that changing core.jar causes many things to be rebuilt. core.jar contains many/all of the core java classes, like Object, String etc. So that every other jar/apk that gets built actually depends on core.jar.
From a makefile perspective, it has no clue what you changed in core.jar, and whether it is safe to not rebuild all these other things that depend on core.jar. It simply sees that the last modified time on core.jar is newer than on all of the other jars/apk that depend on it, so it rebuilds them all.
The trick, however, is to tell make specifically what you want to build, instead of telling it to build everything.
Assuming that you have already done a full build previously, you can simply do
make core snod
The core target will specifically build a new core.jar with your changes, without rebuilding anything that depends on core.jar.
And the snod target (short for systemimage-nodeps) will cause it to repackage everything from out/target/product//system into a new system.img. This is a "special" target that is declared in build/core/Makefile.
In general, the target for a particular jar/apk is simply the name of that jar/apk, without the extension. Alternatively, you can look at the Android.mk file for that module, and find the module name, which is typically something like LOCAL_PACKAGE_NAME or LOCAL_MODULE, depending on the type of module.
For core.jar (in gingerbread at least), the module name is in libcore/JavaLibrary.mk (which is actually included by libcore/Android.mk). This file contains definitions for a number of different modules, but the first one, with LOCAL_MODULE := core is the one resposible for building core.jar. The rest seem to mostly be test related modules.

Should I bundle source and class files in the same JAR?

Separate Jars
When creating JAR files, I've always kept the source separate and offered it as an optional extra.
eg:
Foo.jar
Foo-source.jar
It seems to be the obvious way to do things and is very common. Advantages being:
Keeps binary jar small
Source may not be open / public
Faster for classloader? (I've no idea, just guessing)
Single Jar
I've started to doubt whether these advantages are always worth it. I'm working on a tiny component that is open-source. None of the advantages I've listed above were problems in this project anyway:
Classes + source still trivially small (and will remain that way)
Source is open
Class loading speed of this jar is irrelevant
Keeping the source with the classes does however bring new advantages:
Single dependency
No issues of version mismatch between source and classes
Developers using this jar will always have the source to hand (to debug or inspect)
Those new advantages are really attractive to me. Yes, I could just zip source, classes and even javadoc into a zip file and let clients of my component decide which they want to use (like Google do with the guava libraries) but is it really worth it?
I know it goes against conventional software engineering logic a little, but I think the advantages of a single jar file out-weigh the alternatives.
Am I wrong? Is there a better way?
Yes, I could just zip source, classes and even javadoc into a zip file and let clients of my component decide which they want to use (like Google do with the guava libraries) but is it really worth it?
Of course it is worth it! It takes about 2 seconds to do it, or just a few minutes to change your build scripts.
This is the way that most people who distribute sources and binaries handle this problem.
EDIT
It is not your perspective you need to consider. You have to think of this from the perspective of the people deploying / using your software.
They aren't going to use the source code on the deployment platform.
Therefore putting the source code in the binary JAR is a waste of disc space, slows down deployment and slows down application startup.
If they want to do something about it, they've got a problem. How do they rebuild the JAR file to get rid of the source code? How do they know what is safe to leave out?
From the deployer / user's perspectives, there are no positives, only negatives.
Finally, your point about people not being able to track source versus binary versions doesn't really hold water. Most people who would be interested in the source code are perfectly capable of doing this. Besides, there some simple things you can do to address the issue, like using JAR filenames that include your software's version number, or putting the version number into the manifest.
I have just come across a potential pitfall for the java+classes in a single jar.
If you have java files in a jar and that jar is included in the classpath of a subsequent javac execution, you MUST make sure that the timestamps of the java file is less than the timestamp of the class file.
This scenario can happen when you copy/move the java or class files prior to packaging as a jar.
If the java file is newer than the class, then even though the java file is found on the classpath (rather than an argument to javac), javac will attempt to compile that java file and then potentially end up with duplicate class errors during the compilation stage.
For this reason I would recommend keeping the source in a separate jar to the class files.
Note that relevant flags in javac will not allow you to prefer class over source: http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html#searching
I prefer 'Separate Jars'.
Because binary class jar is for running on JVM, but source not. Source should be carefully maintained by your source control system(SVN). If source needs to release, zip it in separate jar. Many open source separates class jar and source one.
If you want others to test and inspect/improve your code then you can have your source with the binaries. If not, keep the source away from the jar.
How small is small and why should your jar act differently from others?
Unless you have a very good reason why your jar should have the sources, not simply debugging but something specific to this one jar then I'd say no, choice is best.
I say this because if your jar should not be different from other, then you have to work on the assumption that others should do the same as you. If so, the size of the jar is not important, because its duplicated over all "small" jars. Then my WAR is much bigger than needed which, admittedly is not a massive issue, but is not something I would chose for production when I can download sources in DEV so easily.

How to automate a build of a Java class and all the classes it depends on?

I guess this is kind of a follow-on to question 1522329.
That question talked about getting a list of all classes used at runtime via the java -verbose:class option.
What I'm interested in is automating the build of a JAR file which contains my class(es), and all other classes they rely on. Typically, this would be where I am using code from some third party open source product's "client logic" but they haven't provided a clean set of client API objects. Their complete set of code goes server-side, but I only need the necessary client bits.
This would seem a common issue but I haven't seen anything (e.g. in Eclipse) which helps with this. Am I missing something?
Of course I can still do it manually by: biting the bullet and including all the third-party code in a massive JAR (offending my purist sensibilities) / source walkthrough / trial and error / -verbose:class type stuff (but the latter wouldn't work where, say, my code runs as part of a J2EE servlet, and thus I only want to see this for a given Tomcat webapp and, ideally, only for classes related to my classes therein).
I would recommend using a build system such as Ant or Maven. Maven is designed with Java in mind, and is what I use pretty much exclusively. You can even have Maven assemble (using the assembly plugin) all of the dependent classes into one large jar file, so you don't have to worry about dependencies.
http://maven.apache.org/
Edit:
Regarding the servlet, you can also define which dependencies you want packaged up with your jar, and if you are making a stand alone application you can have the jar tool make an executable jar.
note: yes, I am a bit of a Maven advocate, as it has made the project I work on much easier. No I do not work on the project personally. :)
Take a look at ProGuard.
ProGuard is a free Java class file shrinker, optimizer, obfuscator, and preverifier. It detects and removes unused classes, fields, methods, and attributes. It optimizes bytecode and removes unused instructions. It renames the remaining classes, fields, and methods using short meaningless names. Finally, it preverifies the processed code for Java 6 or for Java Micro Edition.
What you want is not only to include the classes you rely on but also the classes, the classes you rely on, rely on. And so on, and so forth.
So that's not really a build problem, but more a dependency one. To answer your question, you can either solve this with Maven (apparently) or Ant + Ivy.
I work with Ivy and I sometimes build "ueber-jar" using the zipgroupfileset functionality of the Ant Jar task. Not very elegant would say some, but it's done in 10 seconds :-)

Categories