2

I've downloaded a JAR file from my teacher's website containing some classes in the default package, and I'm thus unable to access them from inside a defined package.

I have read that the preferable solution is to repackage the JAR, changing the package name. However I have no idea how to go at it. The solution probably involves using Ant or Jar Jar, but I've no experience with either tool. I would love if someone coould point me in the right direction.

Thanks.

user668396
  • 23
  • 1
  • 4

5 Answers5

2

You need to change the sources and recompile then to change the package - simply moving the class files inside the jar (or outside) does not help.

So ask your teacher to give you the sources (or to put the classes in a suitable package), or use a decompiler to do this yourself.

Paŭlo Ebermann
  • 73,284
  • 20
  • 146
  • 210
  • 2
    Yeah, I think I've come to the same conclusion. I just don't understand why they would release anything on the default package. Thanks. – user668396 Mar 20 '11 at 18:17
  • Easy to use Java decompiler if you need it: http://members.fortunecity.com/neshkov/dj.html – Russ Hayward Mar 20 '11 at 18:20
  • @user668396: It either means the jar file is not meant as a library, or your teacher did not understand it. (In older versions of Java, it was still possible to import from the default package.) – Paŭlo Ebermann Mar 20 '11 at 18:29
0

As @Piyush Instructed use the below command for creating a Jar file.
jar -cvf *.* Example.jar

Deepak
  • 2,094
  • 8
  • 35
  • 48
0

If you are using eclipse, just unjar the source files into the source folder of a temporary project. Then, create a new project (the real project you will be working on), and under the java/src directory, create the package structure you want. Then it's just a simple matter of drag-n-dropping the source files from the temporary project into the correct packages in the real project. Eclipse will take care of changing the package declaration of each class for you.

Don
  • 391
  • 2
  • 9
0

To move classes within a jar from the root (unnamed, default) package into a named package (e.g. org.example):

1. Rebuild the Jar from source

Using your IDE, move the classes out of the root/unnamed/default package into a proper named package, and build the jar again.

Simply unzipping the jar and moving the class files around does not help - the class files have to be modified internally, which is what the tools below do.

If you don't have access to the sources, or if you don't want to mess with the source code - there are a couple of solutions I found inspired from this related discussion.

2. Jar Jar Links tool

https://github.com/shevek/jarjar

Its old but still works. Get it from here as discussed here.

The way I used it

# View help
java -jar "bin/jarjar-command-1.0.3.jar" --help

# Run the command
java -jar "jarjar-command-1.0.3.jar" --mode process --rules "rules.txt" target/my.jar --output target/my_new.jar

# View contents of resulting jar
jar tf target/my_new.jar |less

The rules.txt to match root classes is *

rule * com.example.@1

so the rule moves them into the com.example package. The @1 means the thing that was matched.

Unfortunately it doesn't seem to work on classnames involving the $ character - see this issue.

3. Use the Maven Shade Plugin Tool

https://maven.apache.org/plugins/maven-shade-plugin/usage.html

This worked better for my case. Add this fragment to your pom.xml inside the <project>/<build>/<plugins> tag.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.4.1</version>
    <configuration>
        <relocations>
        <relocation>
            <pattern></pattern>
            <shadedPattern>org.example.</shadedPattern>
            <includes>
            <include>TypeScriptParser*</include>
            <include>TypeScriptLexer*</include>
            </includes>
        </relocation>
        </relocations>
    </configuration>
    <executions>
    <execution>
        <phase>package</phase>
        <goals>
        <goal>shade</goal>
        </goals>
    </execution>
    </executions>
</plugin>

To match the classes in the root of the package, I used <pattern></pattern> though there may be a better way.

Also, for my use all my root classes started with TypeScriptParser* or TypeScriptLexer* so I included those explicitly. It took a bit of trial and error to get working on the right classes.

Running this on my build with mvn package did introduce extra classes from my project into the jar that I didn't need, so I had to delete them manually (by unzipping/zipping using jar)

Discussion

Knowing that java files in named packages cannot access classes in the unnamed root package (whether they be in your project or in a jar) was not obvious to me, but was finally explained to me here. I wonder how many Java developers get tripped up by this.

abulka
  • 1,316
  • 13
  • 18
-1

You can unjar/unzip them manually, create the package and jar them back using and IDE or from the command prompt like this. Also, take a look at the ANT documentation on Jar and Unjar which is quite comprehensive.

Piyush Mattoo
  • 15,454
  • 6
  • 47
  • 56
  • As @Paŭlo mentioned, simply unzipping the jar and moving the class files around does not help - the class files have to be modified internally. – abulka May 23 '23 at 22:52