How to create tar file which contains only file - java

I have a file in /tmp/a.crt I will have to make a.tgz which contains a.crt not tmp/a.crt. As i am running tar command through java I can't navigate to /tmp and execute tar -cvf a.tgz a.crt
If i run tar -cvf a.tgz /tmp/a.crt it creates a a.tgz which contains tmp/a.crt .
I tried tar --exclude='/tmp' -cvf a.tgz /tmp/a.crt but while untaring it says
gzip: stdin: not in gzip format
tar: Child returned status 1
Is there any way to achieve my requirement.

If you want to create a compressed tar file (.tgz or .tar.gz), you have to use the option z. Otherwise you have only an uncompressed tar file (.tar). You probably omitted this option during creation.

Here is a Bash session demonstrating what you want (as I understand it):
# first, create test files
$ mkdir tmp
$ touch tmp/a.crt
$ find .
.
./tmp
./tmp/a.crt
# use "-C" to keep the filename out of the archive
$ tar -C tmp -czvf a.tgz a.crt
a.crt
# confirm results
$ tar tf a.tgz
a.crt
As you can see, in the final a.tgz file, there is no tmp/ directory present.
This is generally a bad idea, creating what is sometimes called a "tar bomb" (link). But presumably you have a good reason for it (:

Related

Extract several of jar in one command

I have folders with lots (20) of jar files. Is there a way to extract all those jars in one command in the terminal instead doing it one by one?
I'm using a MAC.
A simple solution.- Get all the jars and extract it
find ./ -name "*.jar" -exec jar -xf {} \;
You can use this from the folder in which all your jars are -
jar {ctxu}[vfm0Mi] [jar-file] [manifest-file] [-C dir]
Options:
-c create new archive
-t list table of contents for archive
-x extract named (or all) files from archive
-u update existing archive
-v generate verbose output on standard output
-f specify archive file name
-m include manifest information from specified manifest file
-0 store only; use no ZIP compression
-M do not create a manifest file for the entries
-i generate index information for the specified jar files
-C change to the specified directory and include the following file
refer the documentation for explaination - http://docs.oracle.com/javase/tutorial/deployment/jar/unpack.html
you may user *.jar in place of jar-file to extract all
This should extract in same location where the jars are present.
jar xvf *.jar

Compiling basic java project

I want to compile a basic java project, https://sourceforge.net/projects/pdfformfiller2 its installation instructions are quite short:
Make sure that iText library, itext-xtra-5.x.0.jar and itextpdf-5.x.0.jar, are accessible to JAVA,
e.g. these are placed in the "lib" subfolder of the current folder.
Get latest ones from: https://sourceforge.net/projects/itext/files/iText/
Compile PdfFormFiller.java
Then from the command line you give command (to see usage help):
java -jar pdfformfiller.jar
I never compiled jars before, and I'm having hard time trying to compile PdfFormFiller correctly. Here's where I've get:
wget -O pdfformfiller.zip https://sourceforge.net/projects/pdfformfiller2/files/latest/download
# author mentions 5.2.0, which is not available anymore, so we go for the latest 5.x:
wget http://kent.dl.sourceforge.net/project/itext/5.5.10/itext5-5.5.10.zip
unzip pdfformfiller.zip
unzip itext5-5.5.10.zip -d pdfformfiller/lib
cd pdfformfiller
javac -cp "lib/*" PdfFormFiller.java
mkdir META-INF
echo -e 'Manifest-Version: 1.0\nClass-Path: pdfformfiller.jar\nMain-Class: PdfFormFiller' > META-INF/MANIFEST.MF
jar -cvfm pdfformfiller.jar META-INF/MANIFEST.MF lib PdfFormFiller.class
Which succeeds without an error, but still doesn't run:
$ java -jar pdfformfiller.jar
Error: Could not find or load main class PdfFormFiller
I guess I'm missing something trivial?
Edit
Complete automation:
iText5=5.5.10
wget -O pdfformfiller.zip https://sourceforge.net/projects/pdfformfiller2/files/latest/download
wget http://kent.dl.sourceforge.net/project/itext/${iText5}/itext5-${iText5}.zip
unzip pdfformfiller.zip
unzip itext5-${iText5}.zip -d pdfformfiller/lib
cd pdfformfiller
mkdir classes
javac -cp "lib/*" -d ./classes/ PdfFormFiller.java
mkdir META-INF
echo 'Manifest-Version: 1.0' > META-INF/MANIFEST.MF
echo "Class-Path: ./lib/itextpdf-${iText5}.jar ./lib/itext-xtra-${iText5}.jar ./lib/itext-pdfa-${iText5}.jar" >> META-INF/MANIFEST.MF
echo 'Main-Class: PdfFormFiller.PdfFormFiller' >> META-INF/MANIFEST.MF
jar -cvfm pdfformfiller.jar ./META-INF/MANIFEST.MF ./lib -C ./classes/ PdfFormFiller
Edit 2
It seems to be the only way to fill pdf form from CLI reliably:
# list fields in a file:
$ java -jar pdfformfiller.jar input.pdf -l
myfield
# prepare field data:
$ echo 'myfield αβγ' > fields
# specify font, fill the fields, flatten the form:
$ java -jar pdfformfiller.jar input.pdf -f fields -font Times_New_Roman.ttf -flatten output.pdf
Works like a charm!
Here are the steps I followed to get it working.
First of all, just for the sake of clarity, let's create a dedicated folder for your compiled classes. It's not mandatory, but just an example of good development practice. I'm omitting the steps of creating folders, changing dirs etc. because it's quite obvious. All commands are run from the project's root directory
javac -cp "lib/*" -d ./classes/ PdfFormFiller.java
Fixing the two main things that were missed:
a) the reference for required lib folder and
b) package name:
echo -e 'Manifest-Version: 1.0\nClass-Path: ./lib/itextpdf-5.5.4.jar ./lib/itext-xtra-5.5.4.jar ./lib/itext-pdfa-5.5.4.jar\nMain-Class: PdfFormFiller.PdfFormFiller' > META-INF/MANIFEST.MF
Assembling jar (please note that additional option: -C is being used here):
jar -cvfm pdfformfiller.jar ./META-INF/MANIFEST.MF ./lib -C ./classes/ PdfFormFiller
This is the final output from executing the resulting jar file:
$ java -jar pdfformfiller.jar
USAGE: pdfformfiller document.pdf [ -l ] [ -v ] [ -f fields_filename ] [ -font font_file ] [ -flatten] [ output.pdf ]
document.pdf - name of source pdf file (required).
-l - only list available fields in document.pdf.
-v - verbose. Use to debug the fields_filename file.
-f fields_filename - name of file with the list of fields values to apply to document.pdf.
if ommited, stdin is used.
-font font_file - font to use. Needed UTF-8 support, e.g. cyrillic and non-latin alphabets.
-flatten - Flatten pdf forms (convert them to text disabling editing in PDF Reader).
output.pdf - name of output file. If omitted, the output if sent to stdout.
fields_filename file can be in UTF-8 as is of the following format:
On each line, one entry consists of 'field name' followed by value of that field without any quotes.
Any number of whitespaces allowed before 'field name', and one space separates 'field name' and its value.
In value, newline characters should be encoded as "\n",
'U+2029 utf-8 E280A9 : PARAGRAPH SEPARATOR PS' should be encoded as "\p",
and '\' characters should be escaped as "\\".
For checkboxes, values are 'Yes'/'Off'.
Based on the Belgian iText library v. 5.2.0, http://www.itextpdf.com/

How to translate an entire folder or package from Java to Objective-C?

I've used an older version of Google's Java to Objective-C (J2ObjC) converter previously (i.e. version 0.5.2) and it was straightforward to translate an entire folder of Java files to their equivalent Objective-C files (and to preserve the directory structure in doing so). I just had to run the following shell executable:
$ ./run.sh —-preservedirs <path to input folder>
I've just downloaded the latest version of J2ObjC (i.e. version 0.9.1) and it's not clear from the Getting Started page or elsewhere how I can translate an entire folder of Java files rather than just a single Java file using the j2obc executable. The only example provided in the Getting Started page is to translate a single Java file which has no dependencies or imports elsewhere as follows:
$ ./j2objc Hello.java
Can anyone provide me with an example of how to translate an entire package assuming I have a folder named input which contains my com package which contains all of the sub-packages and Java files that I want to translate?
To build a whole project, I add the source root(s) to the -sourcepath, then use the find command to locate all Java sources. For example, to build Square.com's Dagger library:
$ export J2OBJC=~/j2objc # change to wherever your distribution is
$ cd ~/src/dagger/core
$ $J2OBJC/j2objc -d build_output -sourcepath src/main/java \
-classpath $J2OBJC/lib/javax-inject.jar \
`find src/main/java -name '*.java'`
All the generated .h and .m files are now in the build_output directory, in subdirectories according to their package (like javac does). To compile all the .m files into a static library, I use:
$ cd build_output
$ j2objcc -c -I. `find . -name '*.m'`
$ libtool -static -o libdagger.a *.o
If there is no better way built into run.sh, you could use find's -exec flag:
find <path to input folder> -type f -exec --preservedirs ./run.sh {} \;
Or, you could use xargs to do multiple files at the same type:
find <path to input folder> -type f | xargs ./run.sh --preservedirs
(You might also need to add -name "*.java" to the find arguments if there are non-Java files in your directories).

Batch Deleting Files While Performing a Copy/Merge

I have 2 files, "launcher.jar" and "camStudio.jar" that I need merged. I decided to try to do this using batch with the code:
copy /b launcher.jar + camStudio.jar file.jar
However, the resulting "file.jar" only contains the contents of "camStudio.jar". How can I prevent the files in "launcher.jar" from being deleted?
Combining the contents of two .jar files is a little more complicated than just calling copy from the command line. Rather than a normal directory, .jar files are a type of compressed file, so you need special utilities to manipulate them. Fortunately these tools come with the standard JKD.
The JDK comes with the utility jar that is unsurprisingly used for manipulating .jar files. It's usage is described as this:
Usage: jar {ctxui}[vfmn0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...
Options:
-c create new archive
-t list table of contents for archive
-x extract named (or all) files from archive
-u update existing archive
-v generate verbose output on standard output
-f specify archive file name
-m include manifest information from specified manifest file
-n perform Pack200 normalization after creating a new archive
-e specify application entry point for stand-alone application
bundled into an executable jar file
-0 store only; use no ZIP compression
-M do not create a manifest file for the entries
-i generate index information for the specified jar files
-C change to the specified directory and include the following file
If any file is a directory then it is processed recursively.
The manifest file name, the archive file name and the entry point name are
specified in the same order as the 'm', 'f' and 'e' flags.
Example 1: to archive two class files into an archive called classes.jar:
jar cvf classes.jar Foo.class Bar.class
Example 2: use an existing manifest file 'mymanifest' and archive all the
files in the foo/ directory into 'classes.jar':
jar cvfm classes.jar mymanifest -C foo/ .
Relevant commands for combining two .jar files are x and c. Even with this, combining the .jar files takes more than a line or two, so I put together this .bat files to automate it.
:: Pass one or more .jar files as command line arguments
:: Combine_Jar [file1] [file2 ...]
:: Combine_Jar Test.jar
:: Combine_Jar Test.jar Test2.jar Test3.jar
#echo off & setlocal enabledelayedexpansion
set "jarDir=%cd%"
set "newJar="
set "folders="
pushd %temp%
for %%a in (%*) do (
call :extract %%a
set "newJar=!newJar!_%%~na_"
)
set "tempDirs=!newJar:_=^"!"
set "tempDirs=%tempDirs:^"^"=^" ^"%"
set "newJar=!newJar:~1,-1!.jar"
set "newJar=!newJar:__=_!"
if exist "!newJar!" del /Q "!newJar!"
jar cf "!newJar!" %tempDirs%
for %%a in (%*) do call rd /s /q "%%~na"
move /Y "!newJar!" "%jarDir%" > nul
popd
exit /B
:extract
set "tempDir=%~n1"
if exist "%tempDir%" (
rd /s /q "%tempDir%"
)
md "%tempDir%"
pushd "%tempDir%"
jar xf "%jarDir%\%~1"
popd
exit /B
It will all jar files passed as arguments into a single jar files.

Comparing two .jar files

How do I compare two .jar files?
Both of them have compiled .class files.
I want the difference in terms of method changes, etc.
JAPICC, sample usage:
japi-compliance-checker OLD.jar NEW.jar
Sample reports for log4j: http://abi-laboratory.pro/java/tracker/timeline/log4j/
PkgDiff, sample usage:
pkgdiff OLD.jar NEW.jar
See sample report for args4j.
Clirr, sample usage:
java -jar clirr-core-0.6-uber.jar -o OLD.jar -n NEW.jar
If you select two files in IntellijIdea and press Ctrl + Dthen it will show you the diff. I use Ultimate and don't know if it will work with Community edition.
Rename .jar to .zip
Extract
Decompile class files with jad
Recursive diff
Extract each jar to it's own directory using the jar command with parameters xvf. i.e. jar xvf myjar.jar for each jar.
Then, use the UNIX command diff to compare the two directories. This will show the differences in the directories. You can use diff -r dir1 dir2 two recurse and show the differences in text files in each directory(.xml, .properties, etc).
This will also show if binary class files differ. To actually compare the class files you will have to decompile them as noted by others.
Create a folder and create another 2 folders inside it like old and new. add relevant jar files to the folders. then open the first folder using IntelliJ. after that click whatever 2 files do you want to compare and right-click and click compare archives.
I use to ZipDiff lib (have both Java and ant API).
Here is my script to do the process described by sje397:
#!/bin/sh
# Needed if running on Windows
FIND="/usr/bin/find"
DIFF="diff -r"
# Extract the jar (war or ear)
JAR_FILE1=$1
JAR_FILE2=$2
JAR_DIR=${PWD} # to assign to a variable
TEMP_DIR=$(mktemp -d)
echo "Extracting jars in $TEMP_DIR"
EXT_DIR1="${TEMP_DIR}/${JAR_FILE1%.*}"
EXT_DIR2="${TEMP_DIR}/${JAR_FILE2%.*}"
mkdir ${EXT_DIR1}
cd ${EXT_DIR1}
jar xf ${JAR_DIR}/${JAR_FILE1}
jad -d . -o -t2 -safe -space -b -ff -s java -r **/*.class
cd ..
mkdir ${EXT_DIR2}
cd ${EXT_DIR2}
jar xf ${JAR_DIR}/${JAR_FILE2}
jad -d . -o -t2 -safe -space -b -ff -s java -r **/*.class
cd ..
# remove class files so the diff is clean
${FIND} ${TEMP_DIR} -name '*.class' | xargs rm
# diff recursively
${DIFF} ${EXT_DIR1} ${EXT_DIR2}
I can run it on Windows using GIT for Windows. Just open a command prompt. Run bash and then execute the script from there.
Use Java Decompiler to turn the jar file into source code file, and then use WinMerge to perform comparison.
You should consult the copyright holder of the source code, to see whether it is OK to do so.
In Linux/CygWin a handy script I use at times is:
#Extract the jar (war or ear)
cd dir1
jar xvf jar-file1
for i in `ls *.class`
do
javap $i > ${i}.txt #list the functions/variables etc
done
cd dir2
jar xvf jar-file2
for i in `ls *.class`
do
javap $i > ${i}.txt #list the functions/variables etc
done
diff -r dir1 dir2 #diff recursively
If you are using IntelliJ IDEA or Android Studio, add your jar files to a project under the libs folder.
Then select the both jar files, right click then select "Compare Archives"
use java decompiler and decompile all the .class files and save all files as project structure .
then use meld diff viewer and compare as folders ..
Here's an aparently free tool http://www.extradata.com/products/jarc/
Please try http://www.osjava.org/jardiff/ - tool is old and the dependency list is large. From the docs, it looks like worth trying.
This application may be what you need, works great and display a simple GUI showing differences. Try Jarcomp

Categories