How to rename a jar file inside another jar file? - jar

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.

Related

FileReader can't find R Script

I try run my R Script within JavaFx. I use Renjin for this purpose and it seems to work properly with statements I run internally. But I want to run an external R Script. The project is set up with Maven so the path should be easy as the R Script is in the resources folder. The path works when I load FXML files, so I'm pretty confused why it can't find my Script.
Here's a short example:
package survey;
import javax.script.*;
import org.renjin.script.*;
import java.io.FileReader;
public class calcFunction {
public static void main(String[] args) throws Exception {
// create a script engine manager:
RenjinScriptEngineFactory factory = new RenjinScriptEngineFactory();
// create a Renjin engine:
ScriptEngine engine = factory.getScriptEngine();
engine.put("x", 4);
engine.put("y", 5);
engine.eval(new FileReader("/test.R"));
}
}
Is something missing? Thanks in advance!
EDIT1:
With my FXML files it works with the "/" path like this:
root = FXMLLoader.load(getClass().getResource("/moduleDa.fxml"));
EDIT2:
Someone who deleted his comment proposed this:
engine.eval(new FileReader(new File(".").getAbsolutePath()+"/test.R"));
It works if the script is in the root directory, where the pom.xml file is located. #James_D made it work so the R script can be located in the resources folder - thanks a lot!
If your R script is bundled as part of the application, it can't be treated as a file - you need to treat it as a resource. Typically, you will deploy your application as a Jar file, and the resources will be elements within that jar file (they won't be files in their own right).
So just treat the R script as a resource and load it as such. I don't know the renjin framework, but I assume ScriptEngine here is a javax.script.ScriptEngine, in which case ScriptEngine.eval(...) takes a Reader as a parameter, and so (if your R script is located in the root of the class path) you can do
engine.eval(new InputStreamReader(getClass().getResourceAsStream("/test.R")));

Some questions about scripts in Gradle

I have to write the script in Gradle and I therefore have some questions.
The script must unpack the .ear file, and then included in the jar, then edit the content and save as ear (text file> jar> ear.)
1) Firstly, I would like to learn how to save a file to the current directory.
(The following code saves the file to another folder.)
task unzip(type: Copy) {
def zipFile = file('C:/Test/file.ear')
def outputDir = file('jar')
from zipTree(zipFile)
into getDestDir()
}
Phrases such as '.', '/' don't work.
2)Secondly, I would like to ask how to unpack the jar file because I can't unpack the above method. (It works only to the EAR)
3)At the end I would ask how you can convert the edited text file on the jar, and then on ear (without dependencies and manifest).
Because the resulting file do I have to file .ear
Thank you in advance for your answer.
You don't want to be writing files into your working directory. All the work should be done under the $buildDir.
A standard method is to set your into directory to a temporary location:
task myTask(type: Copy) {
from 'my/dir/'
into temporaryDir
}
You can unpack a JAR or ZIP file like so:
copy {
from zipTree('path/tozip.zip')
into temporaryDir
}

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

nodejs read image headers

I'm writing a script to download files from urls in a list. The problem I'm having is that the urls don't just point to static files, like file.jpg, they tend to point to servlets that return a file.
What I want to do is download the file for each url and save it with a generic name, then read its headers and rename it with the appropriate extension. (Unless there's a better way)
How could I do that?
I've tried using mime-magic, but it tells me that the extension-less files are directories.
It should work using mime-magic. Are you sure the path is correct and the path is not pointing to a directory?
Otherwise you could use the command line tool file --mime /path/to/file
Here is how to detect an extension of a file using mime-magic:
mime('/path/to/foo.pdf', function (err, type) {
if (err) {
console.error(err.message);
// ERROR: cannot open `/path/to/foo.pdf' (No such file or directory)
} else {
console.log('Detected mime type: %s', type);
// application/pdf
}
});
Note: Added sled's comment as an answer under community-wiki.

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