Install the osgi bundle using the byte array instead of file location? - java

I am trying to install OSGi bundles. I am able to do it successfully. Right now what I am doing is, in our company we have some sort of storage where we are storing all the OSGi bundles jar. So I go and download those OSGi bundles jar into some local directory and then I try to install those bundles from the local location where it got downloaded from my storage repository.
And below method accepts only file location- So I provide my full local file path to this.
context.installBundle(localFilename)
Is there any way, I can install it using the byte[]. Basically I am trying to avoid downloading the jar file from my storage location to some local folder and then use that local location to install the bundles.
private static void callMethod() throws BundleException {
final IStorageServiceClient client = StorageServiceConsumerProvider.getStorageServiceClient(envType);
final StorageObjectIdentifier objIdentifierDir = new StorageObjectIdentifier(name, version, null);
final List<Map<String, String>> dirs = new ArrayList<Map<String, String>>();
client.listDirectory(objIdentifierDir, dirs);
final String filename = name + Constants.DASH + version + Constants.DOTJAR;
final String localFilename = basePath + File.separatorChar + filename;
// first of all, I am trying to delete the jar file from the local folder, if it is already there
new File(localFilename).delete();
final StorageObjectIdentifier objIdentifier = new StorageObjectIdentifier(name, version, filename);
// now I get the byte array of the jar file here.
final byte[] b = client.retrieveObject(objIdentifier);
// now I am writing that jar file to that local folder again using the byte array.
final FileOutputStream fos = new FileOutputStream(localFilename);
fos.write(b);
fos.close();
// now the jar file is there in that location, and now I am using the full path of the jar file to intall it.
BundleContext context = framework.getBundleContext();
List<Bundle> installedBundles = new LinkedList<Bundle>();
installedBundles.add(context.installBundle(localFilename));
for (Bundle bundle : installedBundles) {
bundle.start();
}
}
Is there any way to do this thing without copying the jar file from my storage location to my local folder and then use the full path to my local jar file and then install it?
Can anyone help me with this with a simple example basis on above code? Thanks for the help.

I didn't try it, but BundleContext#installBundle(String, InputStream) should be suitable for this. Using the mentioned method, your code would like this (local file creation has been removed):
private static void callMethod() throws BundleException {
final IStorageServiceClient client = StorageServiceConsumerProvider.getStorageServiceClient(envType);
final StorageObjectIdentifier objIdentifierDir = new StorageObjectIdentifier(name, version, null);
final List<Map<String, String>> dirs = new ArrayList<Map<String, String>>();
client.listDirectory(objIdentifierDir, dirs);
final String filename = name + Constants.DASH + version + Constants.DOTJAR;
final StorageObjectIdentifier objIdentifier = new StorageObjectIdentifier(name, version, filename);
// now I get the byte array of the jar file here.
final byte[] b = client.retrieveObject(objIdentifier);
// now the jar file is there in that location, and now I am using the full path of the jar file to intall it.
BundleContext context = framework.getBundleContext();
List<Bundle> installedBundles = new LinkedList<Bundle>();
installedBundles.add(context.installBundle(fileName, new ByteArrayInputStream(b)));
for (Bundle bundle : installedBundles) {
bundle.start();
}
}

Related

How to get spring boot application jar parent folder path dynamically?

I have a spring boot web application which I run using java -jar application.jar. I need to get the jar parent folder path dynamically from the code. How can I accomplish that?
I have already tried this, but without success.
Well, what have worked for me was an adaptation of this answer.
The code is:
if you run using java -jar myapp.jar dirtyPath will be something close
to this: jar:file:/D:/arquivos/repositorio/myapp/trunk/target/myapp-1.0.3-RELEASE.jar!/BOOT-INF/classes!/br/com/cancastilho/service.
Or if you run from Spring Tools Suit, something like this:
file:/D:/arquivos/repositorio/myapp/trunk/target/classes/br/com/cancastilho/service
public String getParentDirectoryFromJar() {
String dirtyPath = getClass().getResource("").toString();
String jarPath = dirtyPath.replaceAll("^.*file:/", ""); //removes file:/ and everything before it
jarPath = jarPath.replaceAll("jar!.*", "jar"); //removes everything after .jar, if .jar exists in dirtyPath
jarPath = jarPath.replaceAll("%20", " "); //necessary if path has spaces within
if (!jarPath.endsWith(".jar")) { // this is needed if you plan to run the app using Spring Tools Suit play button.
jarPath = jarPath.replaceAll("/classes/.*", "/classes/");
}
String directoryPath = Paths.get(jarPath).getParent().toString(); //Paths - from java 8
return directoryPath;
}
EDIT:
Actually, if your using spring boot, you could just use the ApplicationHome class like this:
ApplicationHome home = new ApplicationHome(MyMainSpringBootApplication.class);
home.getDir(); // returns the folder where the jar is. This is what I wanted.
home.getSource(); // returns the jar absolute path.
File file = new File(".");
logger.debug(file.getAbsolutePath());
This worked for me to get the path where my jar is running, I hope this is what you are expecting.
Try this code
public static String getParentRealPath(URI uri) throws URISyntaxException {
if (!"jar".equals(uri.getScheme()))
return new File(uri).getParent();
do {
uri = new URI(uri.getSchemeSpecificPart());
} while ("jar".equals(uri.getScheme()));
File file = new File(uri);
do {
while (!file.getName().endsWith(".jar!"))
file = file.getParentFile();
String path = file.toURI().toString();
uri = new URI(path.substring(0, path.length() - 1));
file = new File(uri);
} while (!file.exists());
return file.getParent();
}
URI uri = clazz.getProtectionDomain().getCodeSource().getLocation().toURI();
System.out.println(getParentRealPath(uri));

No Such File exception in Runnable Jar file

I am trying to create a runnable jar file. My project includes models.txt file. My project works perfectly in eclipse with no error but when exported to a runnable jar file, It doesn't work. I hereby attach the error and the piece of code where the file is been called.
public static HashMap<String, RenderModel> getModelList(String file) throws IOException {
List<String> data;
HashMap<String, RenderModel> namesToModels = new HashMap<String, RenderModel>();
if (file != null) {
data = Files.readAllLines(Paths.get(file), StandardCharsets.UTF_8);
} else {
String path = "models/models.txt";
data = Files.readAllLines(Paths.get(path), StandardCharsets.UTF_8);
}
Iterator<String> dataIterator = data.iterator();
while (dataIterator.hasNext()) {
String dataLine = dataIterator.next();
System.out.println(dataLine);
String[] line = dataLine.split("; ");
String key = line[0];
String valueObj = line[1];
String valueMtl = line[2];
float scale = Float.parseFloat((String) line[3]);
RenderModel v = new RenderModel(valueObj, valueMtl, scale);
namesToModels.put(key, v);
}
RenderModel v = new RenderModel("custom", "custom", 1.0f);
namesToModels.put("Choose Model from file", v);
return namesToModels;
}
Error Image:
If the files are in the Jar and you cannot read them, try accessing the files by doing:
getClass().getClassLoader().getResource(fileName);
Use this instead for static methods:
ClassName.class.getClassLoader().getResource(fileName);
Where fileName is the name of the file and ClassName the name of the class from which the statement is called.
In your code the path of the model.txt is 'src/models/model.txt'. When your project is packaged the src folder is not included usually. Then you must change the file location; could be better put the file outside the jar, but inside the java classpath.
It does not work because you do not have any file on the path src/models/models.txt when you run your jar else where, this path is only present in your IDE (ofcourse you can place your jar in a location from where it can reach that path, but this is not how it is supposed to be), when you package your project into a jar file it is packed in the package models and you can if you want to have it as default file read it via classpath.

Java: How to copy a folder from one jar to another?

Solved, see my post below
I want to copy files from one .jar to another using java. But not all files of the jar shall be copied. I only want one specific folder to be copied which also can contain subfolders. I already have the code to copy files from one jar to another:
public static void copyFiles(final File file) throws IOException {
final JarFile targetJar = new JarFile(file);
final JarOutputStream output = new JarOutputStream(new FileOutputStream(file));
final JarFile localJar = new JarFile(new File(JarEditor.class.getProtectionDomain().getCodeSource().getLocation().getFile()));
// WRAPPER_CONTENT is a String[] which contains all names of the files i want to copy
for (final String entryName : StringResource.WRAPPER_CONTENT) {
final JarEntry entryToCopy = localJar.getJarEntry(entryName);
final JarEntry targetEntry = new JarEntry(entryName);
output.putNextEntry(targetEntry);
final InputStream input = localJar.getInputStream(entryToCopy);
final byte[] buffer = new byte[10240];
int readByte = 0;
while ((readByte = input.read(buffer)) >= 0) {
output.write(buffer, 0, readByte);
}
}
output.flush();
output.close();
localJar.close();
targetJar.close();
}
Currently im copying the files by running through a hardcoded list of their names. But id prefer a more flexible way so i could add and remove resources from my jar and it still will work. They all have the same parent-folder in the jar. So how would i go through that one folder and only copy those files?
Also maybe worth mentioning, all files which shall be copied are located in the jarfile my runtime is coming from as you probably got from looking at my code.
Thanks for help
Baschdi
Bad luck i guess. I've been searching for the solution for a while now and just when i create this thread i manage to find the solution. I simply check if the name of the jarentry starts with the name of the folder i want to copy. If so, i use the same way as above to copy the jarentry to the other jar. Solved

Copy one file from a folder to another folder in java

I am trying to copy a file form a folder to another folder
i have tried what was suggested in other posts but i have not been successful
Copying files from one directory to another in Java
this has not worked for me
the file is C:/Users/win7/Desktop/G1_S215075820014_T111_N20738-A_D2015-01-26_P_H0.xml
the destination folder is C:/Users/win7/Desktop/destiny
this is the copy code
String origen = "C:/Users/win7/Desktop/G1_S215075820014"
+"_T111_N20738-A_D2015-01-26_P_H0.xml";
String destino = "C:/Users/win7/Desktop/destiny";
private void copiarArchivoACarpeta(String origen, String destino) throws IOException {
Path FROM = Paths.get(origen);
Path TO = Paths.get(destino);
CopyOption[] options =
new CopyOption[] {StandardCopyOption.REPLACE_EXISTING,
StandardCopyOption.COPY_ATTRIBUTES };
java.nio.file.Files.copy(FROM, TO, options);
}
Try:
java.nio.file.Files.copy(FROM, TO.resolve(FROM.getFileName()),
StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
Because the second parameter must be a Path to a file that not yet exists.
Just like the docu sais:

Creating folder in the local file system

I'm having the following code in my mapper [ Hadoop - Map Reduce ]
Im trying to create a folder in the shared path
protected void setup(Context context)
throws IOException,InterruptedException
{
fileName1 = ((FileSplit) context.getInputSplit()).getPath().getName().toString();
Directory = "\\\\DEV144\\MapperFile\\"+fileName1;
File directory1 = new File(Directory);
if (!directory1.exists())
{
boolean result = new File(Directory).mkdirs();
System.out.println(Directory);
if(result)
{
System.out.println("DIR created");
System.out.println(Directory);
}
}
mos = new MultipleOutputs(context);
above code is not creating the folder. But when i give something like this
Directory = "E:\\MapperFile\\"+fileName1;
File directory1 = new File(Directory);
And point the local system it is creating Folder and working fine
My question is why it is not able to create folder in the shared path ?
And what is wrong in my code
I had a similar problem and I start using jCIFS. I have to point out that this was used to access windows shared directory from a linux machine. For creating directory you can use:
String smbUrl = "smb://domain;username:password#server/share/myNewDirectory";
SmbFile smbFile = new SmbFile(smbURL);
try{
smbFile.mkdir();
}catch(SmbException e){...}
And don't forget to check if you have sufficient permissions for a java application.

Categories