How to load a MANIFEST.MF file into a JAR properly? - jar

I don't want to create a 'default manifest file', I just want to load the Manifest file(which I already created as per my requirements) into the JAR as it is. I used the command JAR uf, the MANIFEST.MF is not even loaded into the JAR. And then I tried JAR cvf, the MANIFEST.MF file was loaded with modified data(probably default manifest). What is the correct command to load MANIFEST.MF file into a JAR?
Also, the other files in JAR are .xml, .data, .properties which are all loaded successfully.

For Jar:
JarInputStream jarStream = new JarInputStream(stream);
Manifest mf = jarStream.getManifest();
From servlet its possible to use also:
try(InputStream in = servletContext.getResourceAsStream("/META-INF/MANIFEST.MF")) {
return ....;
} catch (IOException e) {
throw Throwables.propagate(e);
}

Related

How to rename a jar file inside another jar file?

I have jar foo.jar which contains jar foo/config/baar-temp.jar.
What is the best method to rename baar-temp.jar to baar.jar?
Actually, jar format is based on zip and can be operated on as a file system using for example ZipFileSystemProvider available in Java7. That allows us to do a rather simple manipulation with the insides of one:
private void renameStuffInsideJar(String jarFilePath){
URI uri = URI.create("jar:file:"+jarFilePath);
try {
FileSystem jarFile = FileSystems.getFileSystem(uri)) {
Path pathInJarfile = jarFile.getPath("foo/config/baar-temp.jar");
Files.move(pathInZipfile,pathInZipfile.resolveSibling("baar.jar"));
} catch(IOException e){
//TODO
}
}
Alternatively, if it's not code you want, you could just open your jar file in your preferred archive manager like 7zip or WinRar and rename it using that.

How to copy a file to an empty directory through gradle

I'm writing a Javafx Application where I had to include a fxml file to copy from the source to the build directory. This is my task.
task copyRequiredFiles(type: Copy) {
from '/src/com/indywiz/game/ui/view/Game2048.fxml'
into 'build/classes/main/com/indywiz/game/ui'
}
task (runui, dependsOn: ['classes', 'copyRequiredFiles'], type: JavaExec) {
main = 'com.indywiz.game.ui.Main'
classpath = sourceSets.main.runtimeClasspath
}
If I run runui task, I get Skipping task ':copy Required Files' as it has no source files.
What is going wrong? Please let me know if you need any more information.
Below is my folder structure:
You gave an absolute part for from, but it needs to be a relative path (i.e. no leading /).

Gradle: How to add resource (not lib) jars to root of war?

In the continuing saga of attempting to migrate from an insanely complicated ant build to gradle - We have some resource jar files for 'javahelp' that I'm generating. They contain no classes. I need to add the output of the project that creates these resource jars to the root of my war (not to WEB-INF/lib).
My attempted solution:
apply plugin: 'war'
//Move files into position for the mmplEar project
task stage(overwrite: true, dependsOn: war) << {
}
war {
from project(':help:schedwincli').buildDir.absolutePath + '/libs'
include '*.jar'
}
dependencies {
//Ensure the jar is generated, but we don't want it in the lib dir
providedCompile project(':help:schedwincli')
}
This compiles and runs, and the :help:schedwincli does run and generate the needed jar, however when I open up my war file, the expected jar is not present anywhere in the war. Suggestions?
Edit
I made the changes suggested by Peter below, but now I get this error:
Could not find property 'resources' on configuration container.
This is where it says it's failing:
from '../../runtime', /*Fails on this line*/
'../../runtime/html',
'../../runtime/html/Jboss',
'../../runtime/props',
'../../runtime/props/Jboss',
'../../scripts',
'../../../proj/runtime',
'../../../proj/runtime/html',
'../../../proj/runtime/html/Jboss',
'../../../proj/runtime/props',
'../../../proj/runtime/props/Jboss',
configurations.resources
include '*.css'
include '*.gif'
include '*.html'
include '*.jpg'
include '*.jnlp'
include '*.props'
include '*.properties'
include 'jsps/**'
include '*.jar'
include 'log4j/**'
include 'setupLdap.cmd'
include 'spreadsheets/*.xlsx'
You want something like:
configurations {
resources
}
dependencies {
resources project(':help:schedwincli')
}
war {
from configurations.resources
}

Migrating project to Servlet - properties file

I am migrating a project to a servlet.
I put the jars in the lib directory, the compiled classes in classes directory.
However, I have some files (properties, a wsdl file) that I am loading and reading in my application. For example this is how I am loading my properties:
try {
InputStream in = new BufferedInputStream(new FileInputStream("my.prop"));
myConfig.load(in);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
Where do those files that I am loading go?
They usually go straight in the classpath so that you aren't dependent on the current working directory of the local disk file system. But you've got to change the way how you're getting an inputstream:
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("my.prop");
See also:
Where to place and how to read configuration resource files in servlet based application?
getResourceAsStream() vs FileInputStream

how to check the version of jar file?

I am currently working on a J2ME polish application, just enhancing it. I am finding difficulties to get the exact version of the jar file.
Is there any way to find the version of the jar file for the imports done in the class? I mean if you have some thing, import x.y.z; can we know the version of the jar x.y package belongs to?
Decompress the JAR file and look for the manifest file (META-INF\MANIFEST.MF). The manifest file of JAR file might contain a version number (but not always a version is specified).
You need to unzip it and check its META-INF/MANIFEST.MF file, e.g.
unzip -p file.jar | head
or more specific:
unzip -p file.jar META-INF/MANIFEST.MF
Just to expand on the answers above, inside the META-INF/MANIFEST.MF file in the JAR, you will likely see a line: Manifest-Version: 1.0 ← This is NOT the jar versions number!
You need to look for Implementation-Version which, if present, is a free-text string so entirely up to the JAR's author as to what you'll find in there.
See also Oracle docs and Package Version specificaion
Just to complete the above answer.
Manifest file is located inside jar at META-INF\MANIFEST.MF path.
You can examine jar's contents in any archiver that supports zip.
Each jar version has a unique checksum. You can calculate the checksum for you jar (that had no version info) and compare it with the different versions of the jar. We can also search a jar using checksum.
Refer this Question to calculate checksum:
What is the best way to calculate a checksum for a file that is on my machine?
Basically you should use the java.lang.Package class which use the classloader to give you informations about your classes.
example:
String.class.getPackage().getImplementationVersion();
Package.getPackage(this).getImplementationVersion();
Package.getPackage("java.lang.String").getImplementationVersion();
I think logback is known to use this feature to trace the JAR name/version of each class in its produced stacktraces.
see also http://docs.oracle.com/javase/8/docs/technotes/guides/versioning/spec/versioning2.html#wp90779
Thought I would give a more recent answer as this question still comes up pretty high on searches.
Checking CLi JAR Version:
Run the following on the CLi jar file:
unzip -p jenkins-cli.jar META-INF/MANIFEST.MF
Example Output:
Manifest-Version: 1.0
Built-By: kohsuke
Jenkins-CLI-Version: 2.210 <--- Jenkins CLI Version
Created-By: Apache Maven 3.6.1
Build-Jdk: 1.8.0_144
Main-Class: hudson.cli.CLI
The CLi version is listed above.
To get the Server Version, run the following:
java -jar ./jenkins-cli.jar -s https://<Server_URL> -auth <email>#<domain>.com:<API Token> version
(the above will vary based on your implementation of authentication, please change accordingly)
Example Output:
Dec 23, 2019 4:42:55 PM org.apache.sshd.common.util.security.AbstractSecurityProviderRegistrar getOrCreateProvider
INFO: getOrCreateProvider(EdDSA) created instance of net.i2p.crypto.eddsa.EdDSASecurityProvider
2.210 <-- Jenkins Server Version
This simple program will list all the cases for version of jar namely
Version found in Manifest file
No version found in Manifest and even from jar name
Manifest file not found
Map<String, String> jarsWithVersionFound = new LinkedHashMap<String, String>();
List<String> jarsWithNoManifest = new LinkedList<String>();
List<String> jarsWithNoVersionFound = new LinkedList<String>();
//loop through the files in lib folder
//pick a jar one by one and getVersion()
//print in console..save to file(?)..maybe later
File[] files = new File("path_to_jar_folder").listFiles();
for(File file : files)
{
String fileName = file.getName();
try
{
String jarVersion = new Jar(file).getVersion();
if(jarVersion == null)
jarsWithNoVersionFound.add(fileName);
else
jarsWithVersionFound.put(fileName, jarVersion);
}
catch(Exception ex)
{
jarsWithNoManifest.add(fileName);
}
}
System.out.println("******* JARs with versions found *******");
for(Entry<String, String> jarName : jarsWithVersionFound.entrySet())
System.out.println(jarName.getKey() + " : " + jarName.getValue());
System.out.println("\n \n ******* JARs with no versions found *******");
for(String jarName : jarsWithNoVersionFound)
System.out.println(jarName);
System.out.println("\n \n ******* JARs with no manifest found *******");
for(String jarName : jarsWithNoManifest)
System.out.println(jarName);
It uses the javaxt-core jar which can be downloaded from http://www.javaxt.com/downloads/
I'm late this but you can try the following two methods
using these needed classes
import java.util.jar.Attributes;
import java.util.jar.Manifest;
These methods let me access the jar attributes. I like being backwards compatible and use the latest. So I used this
public Attributes detectClassBuildInfoAttributes(Class sourceClass) throws MalformedURLException, IOException {
String className = sourceClass.getSimpleName() + ".class";
String classPath = sourceClass.getResource(className).toString();
if (!classPath.startsWith("jar")) {
// Class not from JAR
return null;
}
String manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1) +
"/META-INF/MANIFEST.MF";
Manifest manifest = new Manifest(new URL(manifestPath).openStream());
return manifest.getEntries().get("Build-Info");
}
public String retrieveClassInfoAttribute(Class sourceClass, String attributeName) throws MalformedURLException, IOException {
Attributes version_attr = detectClassBuildInfoAttributes(sourceClass);
String attribute = version_attr.getValue(attributeName);
return attribute;
}
This works well when you are using maven and need pom details for known classes. Hope this helps.
For Linux, try following:
find . -name "YOUR_JAR_FILE.jar" -exec zipgrep "Implementation-Version:" '{}' \;|awk -F ': ' '{print $2}'
If you have winrar, open the jar with winrar, double-click to open folder META-INF. Extract MANIFEST.MF and CHANGES files to any location (say desktop).
Open the extracted files in a text editor: You will see Implementation-Version or release version.
You can filter version from the MANIFEST file using
unzip -p my.jar META-INF/MANIFEST.MF | grep 'Bundle-Version'
best solution that does not involve extracting the jar files is to run the following command. If the jar file does not contain a manifest file you will get a "WARNING: Manifest file not found"
java -jar file.jar -v
Just rename the extension with .zip instead of .jar. Then go to META-INF/MANIFEST.MF and open the MANIFEST.MF file with notepad. You can find the implementation version there.
It can be checked with a command java -jar jarname

Resources