Use existing Java classes from Jython REPL? - java

I have a massive, unfamiliar Java codebase that I need to use in one of my projects, and unfortunately it's one of those situations where almost nothing is documented, and the very few things that are documented are of the "setFoo(Foo foo) - sets the foo." variety. So the documentation generated with javadoc is not as helpful as it could be.
I'm more of a Lisp and Python guy myself, so my first thought was that I could learn a lot by interactively playing with some of the relevant classes. Enter the Jython REPL. The problem is that I can't figure out how to set the...the whatever (classpath?) to use them. Assume that I have two directories containing the subdirectories containing the .java files: ~/project/foo/src/ and ~/project/bar/src/.
Thanks in advance.

It sounds like you first need to compile those Java classes (you've referenced src directories in your question).
Once you have classes compiled, you can reference them via the classpath.
e.g.
>>> import sys
>>> sys.path.append(r'C:\temp\sample.jar')
>>> from org.my.package import MyClass
More info in this document

Related

Do I always have to type package name in Java?

Today I started learning Java.
I saw that package automatic gets included in .Java file.
I was wondering if it always need to be included?
Consider specify a common package for all the types within a same project.
In Java is common to start a project with a specific package setting. A package creates a namespace to disambiguate the types that it includes, to play nicelly with other projects that may or may not be in the same classpath. Normally, the package is bound to a URL of the project.
Think of Java packages like C++ namespaces.
A huge project/product written in Java can depend on lots and lots of projects, each described in a different package.
Organizations like Apache have lots of projects, organized under a common package pattern: org.apache.<<name_of_the_project>>.
Consider starting your project with a package named: com.user3552670; or something like your personal site, so persons that will consume your project can relate to the creator.
Yes and no.
It's used to specify the package of the class, read more here.
You could create a class without a package, but your code will look bad..
They exists to avoid conflicts, example between your code and default java package.
If packages doesn't exists, you can't create a class named ArrayList because already exists in Java.
Some IDEs force the fact that, if your .java file is in com/a/b/c folder his package should be com/a/b/c (If i don't remember wrong, IntellIJ IDEA do that)
Yes and no.
It must be there, but the IDE takes care of it (I don't use Netbeans, but I'd bet that it can do it, too). When moving files between packages, it has to be updated, but again, the IDE does it all.

Jars with default package

I found this question -> Import custom libraries in Java
And #Andy Thomas-Cramer said that the classes in "stdlib.jar" from "An introduction to programming in Java" have no packages, so they are in the default package.
Isn't this a bad practice? If you have something with no package the IDEs' auto-completion is quite slower. And also this means that we could not use any of the classes, in that jar, from classes with packages different then the default?
Can someone please tell me how we could deal with this?
EDIT:
I have 2 jars and I put them in Referenced libraries, they both have a bunch of classes in default package. When I create class in different package then the default - lets say org.myquestion I can't access the classes from the jars anymore.
This is something that really bugs me... First I can't create my own package and use anything from the jars. Second my IDE's (I use eclipse) auto-complete goes terrible - I guess it searches to meany classes at once... What I want to do is to put somehow the jars in some namespace... and to be able to access them like org.someones.libs.SomeClass
It certainly is bad practice to use the default package. A package groups classes and provides them with access protection (protected, package private) and functions as a unique namespace.
You can always use classes from every package, them being default or not, you can always mix.
Download the jar source code, And built it to jar by yourself and added the package name whatever your like.That's will solve your problem.
Importing classes inside JAR files that are in the default package
I ran into the exactly same problem as you did. The problem is the jar file "stdln.jar" has no named package, say, only with default package.
You cannot import a class from a default package, basically, since the import operation needs the package name:
import packagename.*;
So there are only two way to fix this problem:
the easier one: Do not create a package in your src folder and use default package two! Every class in stdln.jar would be imported to your src automatically.
Like this:
enter image description here
try to create your own jar file with a named package and copy all the class file into your newly-created jar file.
Since the stdln.jar is only used for education, so which you are gonna choose does not really matter. In real development, we never use default named package since it's not really a good practice, always leading to some confusing stuff.
Hope this would help you!

How to decompile obfuscated java programs avoiding class/package name collisions

I want to decompile a java program and recompile the derived (obfuscated) source. I unpacked the .jar archive and got a directory structure like that:
com/
com/foo/A/
com/foo/A/A.class
com/foo/A/B.Class
com/foo/B/A.class
...
com/foo/A.class
com/foo/B.class
org/foo/Bar.class
...
The problem is that there are name collisions between packages and classes, which makes it impossible to recompile the decompiled class files.
A decompiled class will look like this:
package org.foo;
import com.foo.A; // <-- name collision error
class Bar {
...
}
Is there any way to resolve those naming issues, without renaming the class files?
EDIT:
This is not a decompiler problem, but the question how it is possible to have a working .jar file with classes that violate naming conventions.
EDIT2:
Okay, i guess on bytecode level such naming is possible, so with a smarter decompiler (who automatically renames the classes and fixes their references) this problem could be solved.
Do you really need to unpack the entire jar and recompile everything? Instead of recompiling the entire decompiled source by itself, use the original jar as the classpath, and extract and recompile only those classes that you need to modify. Then, when you need to package up your recompiled code, just copy the original jar and use jar -uf to replace the modified class files in place:
jar -uf ./lib/copy_of_original_jar_file.jar -C ./bin com/foo/A.class com/foo/B.class [...]
...and ./lib/copy_of_original_jar_file.jar becomes your new library.
One thing is for sure, and that is that the original jar must work properly with a Java classloader in order for the program to run. It should work just as well for compiling your one-off .class files.
You should experience much fewer naming collision issues by using the original jar because you keep the same classpath scanning order that the running application would use. Not only that, but Java decompilers aren't perfect. By eliminating the majority of the decompiled code from recompilation, you avoid the majority of issues that decompilers have with things like exception handler overlaps, special characters in obfuscated symbols, variable scoping issues, etc.
Java's import mechanism provides a shorthand for naming things, but you obviously cannot use it when there are collisions. You can always use the fully qualified name in your code, e.g.
package org.foo;
class Bar {
private com.foo.Bar aDifferentBar;
...
}
EDIT:
I suppose there could be class files that comply with the JVM spec but which cannot be produced by a Java program that complies with the JLS spec. If so then you'll definitely need a smarter decompiler.
You can not import packages in Java, so why should this be a name collision? Which error message do you get from the compiler?
If there would be a name collision in the obfuscated code, the code would not run. So the decompiled code should be collision free.

Do Eclipse's Refactoring Tools Violate The Java Language Specification?

In Eclipse 3.5, say I have a package structure like this:
tom.package1
tom.package1.packageA
tom.package1.packageB
if I right click on an the tom.package1 package and go to Refactor->Rename, an option "Rename subpackages" appears as a checkbox. If I select it, and then rename tom.package1 to tom.red my package structure ends up like this:
tom.red
tom.red.packageA
tom.red.packageB
Yet I hear that Java's packages are not hierarchical. The Java Tutorials back that up (see the section on Apparent Hierarchies of Packages). It certainly seems like Eclipse is treating packages as hierarchical in this case.
I was curious why access specifiers couldn't allow/restrict access to "sub-packages" in a previous question because I KNEW I had seen "sub-packages" referenced somewhere before.
So are Eclipse's refactoring tools intentionally misleading impressionable young minds by furthering the "sub-package" myth? Or am I misinterpreting something here?
Eclipse can't possibly violate the JLS in this case, because it has nothing to do with compiling or running Java source or bytecode.
The refactoring tools behave as they do because that behaviour is useful to developers. The behaviour is useful to developers because, for many intents and purposes, we do treat packages as hierarchal (a.b.c has some kind of relationship with a.b, even if that relationship is not consistent from project to project). That doesn't mean Java treats them as hierarchal intrinsically.
One example where people treat packages as very hierarchal is in configuring a logging framework such as log4j. Again, it's not intrinsic to log4j, but that's how people use it in practice.
Java packages are not hierarchical in the sense that importing everything from package A does not import everything from package A.B.
However, Java packages do correspond directly to the directory structure on the file system, and directories are hierarchical. So Eclipse is doing the correct thing - it is renaming the directory, which automatically changes the name of the parent directory of the renamed directory's children (to state the very obvious).
even java itself has the concept of subpackage:
http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/java.html
java -ea[:<package name>"..." | :<class name> ]
Enable assertions. Assertions are disabled by default.
With no arguments, enableassertions or -ea enables assertions. With one argument ending in "...", the switch enables assertions in the specified package and any subpackages. If the argument is simply "...", the switch enables assertions in the unnamed package in the current working directory. With one argument not ending in "...", the switch enables assertions in the specified class.
If a single command line contains multiple instances of these switches, they are processed in order before loading any classes. So, for example, to run a program with assertions enabled only in package com.wombat.fruitbat (and any subpackages), the following command could be used:
java -ea:com.wombat.fruitbat... <Main Class>
Java's packages are not hierarchical, but Eclipse stores packages on your system's file structure.
tom.package1.packageA is represented on a Windows file system as tom/package1/packageA.
When you ask Eclipse to refactor a package name, you're asking Eclipse to change the name of the file system directory structure.
You can have packages in Eclipse like:
tom.package1.packageA
tom.package2.packageB
tom.package3.packageC
You'll just have different 2nd level file system directories.

Modern equivalent of javadeps?

I am looking for a replacement for javadeps, which I used to use to generate sections of a Makefile to specify which classes depended on which source files.
Unfortunately javadeps itself has not been updated in a while, and cannot parse generic types or static imports.
The closest thing I've found so far is Dependency Finder. It almost does what I need but does not match non-public classes to their source files (as the source filename does not match the class name.) My current project has an interface whose only client is an inner class of a package-private class, so this is a significant problem.
Alternatively if you are not aware of a tool that does this, how do you do incremental compilation in large Java projects using command-line tools? Do you compile a whole package at a time instead?
Notes:
javadeps is not to be confused with jdepend, which is for a very different purpose.
This question is a rewrite of "Tool to infer dependencies for a java project" which seemed to be misunderstood by 2 out of 3 responders.
I use the <depend> task in ant, which is ok, but not 100% trustworthy. Supposedly JavaMake can do this dependency analysis, but it seems to be rarely updated and the download page is only sometimes available.

Categories