How to capture video using JMF, but without installing JMF - java

A videoconferencing project I was working on used JMF to capture video and audio, and transmit it to another endpoint. An issue was that my team didn't want the user of the product to have to install JMF.
I thought it might be worthwhile to share our solution to this problem. It works. It works well. My question to you is: does anyone have a better way to do it?
Environment: Windows, XP and above
Download JMF for Windows
Install it on your machine
Locate the following dlls in the system32 folder after jmf installs:
jmacm.dll
jmam.dll
jmcvid.dll
jmdaud.dll
jmdaudc.dll
jmddraw.dll
jmfjawt.dll
jmg723.dll
jmgdi.dll
jmgsm.dll
jmh261.dll
jmh263enc.dll
jmjpeg.dll
jmmci.dll
jmmpa.dll
jmmpegv.dll
jmutil.dll
jmvcm.dll
jmvfw.dll
jmvh263.dll
jsound.dll
Copy the dlls into a temporary folder
Locate the jmf.properties file (Do a search on your computer for it)
Download the JMF source code
In the source code, find the following files:
JMFinit.java
JMRPropertiesGen.java
Registry.java
RegistryGen.java
Create a package; I'll call it JMFNoInstall
Add the files listed in step 6
Add a class called Main to this package as such:
package JMFNoInstall;
// add your imports and whatnot here
public class Main()
{
public Main()
{
JMFinit.main(null);
JMFPropertiesGen.main(null);
Registry.main(null);
RegistryGen.main(new String[] {
new File(".").getAbsolutePath(),
"registrylib"
});
}
}
The jmf.properties file needs to go in the same folder as the class that has your main method or the same folder as the JAR archive that contains the main method.
The dlls need to go into the win32 folder. You can have your program check to see if they are in the win32 folder. If they are not, you can have it copy them over from some location. The jmf.properties file gets updated whenever the the Main class listed above runs. You only need to run this once, the first time the program is ever run, or if the user would like to add new capture devices. Lastly, just make sure the jmf.jar file and jmfcom.jar that comes along with the Windows JMF download is included in the classpath. You're good to go at this point. All the functionality of JMF without actually having to install it.
There really isn't a lot of work involved with this, and you can incorporate it into your custom installer quite easily.
Has anyone found a better way to do this though? There are a few pitfalls of doing it this way.
EDIT: I thought it might be worthwhile to share some of the code that I created. Of course youll need to modify it to handle what you. It prob wont compile, but the stuff that is missing should be easy enough to recreate. But thought it might be a good starting point to help people. The detectCaptureDevices function is probably what will help most people. Ill update this class as I go.
import GUI.Window;
import GlobalUtilities.OS;
import GlobalUtilities.ProgressBar;
import GlobalUtilities.FileUtilities;
import java.io.File;
import java.util.ArrayList;
import java.util.Vector;
import javax.swing.text.Utilities;
/**
* This class providex easy access to the most needed info about JMF. You can test
* a JMF install (Windows only currently) and also get info about the captrue
* devices hooked up to JMF.
* #author dvargo
*/
public class JMFRunner
{
/**
* Show the status of operations
*/
final ProgressBar theBar = new ProgressBar();
/**
* Location where the dll's JMF relies on need to be placed
*/
final String windowsDllFolder = "C:\\WINDOWS\\system32\\";
final String linuxDllFolder = "/usr/lib/";
/**
* Dll's that JMF uses
*/
final String[] windowsDllList = new String[]{
"jmacm.dll",
"jmam.dll",
"jmcvid.dll",
"jmdaud.dll",
"jmdaudc.dll",
"jmddraw.dll",
"jmfjawt.dll",
"jmg723.dll",
"jmgdi.dll",
"jmgsm.dll",
"jmh261.dll",
"jmh263enc.dll",
"jmjpeg.dll",
"jmmci.dll",
"jmmpa.dll",
"jmmpegv.dll",
"jmutil.dll",
"jmvcm.dll",
"jmvfw.dll",
"jmvh263.dll",
"jsound.dll"};
String[] linuxDllList = new String[]{
"libjmcvid.so",
"libjmdaud.so",
"libjmfjawt.so",
"libjmg723.so",
"libjmgsm.so",
"libjmh261.so",
"libjmh263enc.so",
"libjmjpeg.so",
"libjmmpa.so",
"libjmmpegv.so",
"libjmmpx.so",
"libjmutil.so",
"libjmv4l.so",
"libjmxlib.so"
};
String [] dlls= null;
String dir = null;
/**
* List of the video capture devices found by JMF
*/
Vector videoDevices = null;
/**
* List of the audio capture devices found by JMF
*/
Vector audioDevices = null;
public JMFRunner()
{
if(OS.isWindows())
{
dlls = windowsDllList;
dir = windowsDllFolder;
}
else if(OS.isLinux())
{
dlls = linuxDllList;
dir = linuxDllFolder;
}
else
{
Window.getLogger().severe("Operating system does not support JMF");
}
}
/**
* Adds new capture devices
*/
public void detectCaptureDecives()
{
Thread theTread = new Thread(theBar);
theTread.start();
theBar.repaint();
JMFInit.main(new String[] {""});
JMFPropertiesGen.main(new String[] {""});
Registry.main(new String[] {""});
RegistryGen.main(new String[] {"-d",
new File(".").getAbsolutePath(),
"registrylib"
});
theBar.setMessage("");
theBar.stop();
}
/**
* Verifies that all the dll's that JMF needs are in their correct spot
* #return True if all dlls are in their correct spot, false otherwise
*/
public boolean detectDlls()
{
boolean retVal = true;
String currFile;
for(String currDll : dlls)
{
currFile = dir + currDll;
if(! new File(currFile).exists())
{
Window.getLogger().severe("Can not find dll " + currFile + " for JMF");
retVal = false;
}
}
return retVal;
}
//Doesnt work quite yet
public boolean installLibraryFiles()
{
boolean retVal = true;
String currFile;
for(String currDll : dlls)
{
currFile = dir + currDll;
File newDll = new File(currFile);
//see if this dll is already there
if(!newDll.exists())
{
//its not there so lets copy it
try
{
FileUtilities.copy(newDll,FileUtilities.getResourceFile("/JMFManager/Resources/"+currDll,currDll));
}
catch(Exception e)
{
retVal = false;
}
}
}
return retVal;
}
/**
* Returns the location of the jmf.properties file that STix is using
* #return THe locaiton of the JMF properties
*/
public String getJMFPropertiesFileLocation()
{
return Registry.getJMFPropertiesFileLocation();
}
/**
* Returns a list of the audio devices found by JMF
* #return Returns an Arraylist containing info about the audio capture devices
*/
public ArrayList getAudioDevices()
{
DeviceFinder df = new DeviceFinder();
audioDevices = df.getSoundCaptureDevices();
return new ArrayList(audioDevices);
}
/**
* Returns a list of the video decives deteced by JMF
* #return returns an arraylist with info of the video capture devices
*/
public ArrayList getVideoDevices()
{
DeviceFinder df = new DeviceFinder();
videoDevices = df.getVideoCaptureDevices();
return new ArrayList(videoDevices);
}
public static void main(String [] args)
{
JMFRunner x = new JMFRunner();
//x.detectCaptureDecives();
x.installLibraryFiles();
System.out.println(x.detectDlls());
System.out.println(x.getJMFPropertiesFileLocation());
System.out.println(x.getAudioDevices());
System.out.println(x.getVideoDevices());
}
}
DeviceFinder.java
import java.util.Vector;
import javax.media.*;
import javax.media.format.*;
/**
* this class gets information about capture devices (mics and cameras)
*/
public class DeviceFinder {
Vector videoDevices = new Vector();
Vector audioDevices = new Vector();
/**
* Constructor
* Creates a new DeviceFinder
*/
public DeviceFinder()
{
/*retrieve ALL video and audio devices*/
videoDevices = CaptureDeviceManager.getDeviceList(new VideoFormat(null));
audioDevices = CaptureDeviceManager.getDeviceList(new AudioFormat(null));
}
/**
* purpose: Get information on all Video capture devices on the system
* #return java.util.Vector a vector of attributes
*/
public Vector getVideoCaptureDevices()
{
return videoDevices;
}
/**
* purpose: Get information on all audio capture devices on the system
* #return java.util.Vector a vector of attributes
*/
public Vector getSoundCaptureDevices()
{
return audioDevices;
}
/**
* retrieve the first video capture device
*/
public CaptureDeviceInfo getPrimaryVideoCaptureDevice()
{
return (CaptureDeviceInfo)videoDevices.get(0);
}
/*retrieve the first audio capture device*/
public CaptureDeviceInfo getPrimaryAudioCaptureDevice()
{
return (CaptureDeviceInfo)audioDevices.get(0);
}
/**
* get the first video device name
* #return String the name of the video device
*/
public String getVideoCaptureDeviceName()
{
return ((CaptureDeviceInfo)videoDevices.get(0)).getName();
}
/**
* get the first audio device name
* #return String the name of the audio device
*/
public String getAudioCaptureDeviceName()
{
return ((CaptureDeviceInfo)audioDevices.get(0)).getName();
}
/**
* get the first video device media locator
* #return MediaLocator
*/
public MediaLocator getVideoMediaLocator()
{
return ((CaptureDeviceInfo)videoDevices.get(0)).getLocator();
}
/**
* get the first audio device media locator
* #return MediaLocator
*/
public MediaLocator getAudioMediaLocator()
{
return ((CaptureDeviceInfo)audioDevices.get(0)).getLocator();
}
/**
* get the video device media locator at index idx
* #param idx index of the media locator (0 is the first/default,
* as ordered by
* the JMFRegistry)
* #return MediaLocator
*/
public MediaLocator getVideoMediaLocator(int idx)
{
if(idx >= videoDevices.size())
{
return null;
}
return ((CaptureDeviceInfo)videoDevices.get(idx)).getLocator();
}
/**
* get the audio device media locator at index idx
* #param idx index of the audio device (as ordered by the JMFRegistry)
* #return MediaLocator
*/
public MediaLocator getAudioMediaLocator(int idx)
{
return ((CaptureDeviceInfo)audioDevices.get(idx)).getLocator();
}
/**
*
* #param args
*/
public static void main(String[] args)
{
DeviceFinder df = new DeviceFinder();
//DEBUG:
System.out.println(df.getVideoMediaLocator());
System.out.println(df.getAudioMediaLocator());
}
}

I don't think there is a better way. Unless the DLLs are explicitly loaded by path name, you would just need to make sure they are in the system path, so if they lived right next to the JVM executables it should also work. Windows does implicitly include the directory the program was started from in the system path, so that is another potential location.
Installers are a double edged sword, they make it easy to add new functionality and remove it later, but they also make it harder to deploy solutions that use the product.
One of the nice things about Java in general is that you don't have to install it for it to work. Essentially, once you perform the install of the JRE on one system, you can bundle it up and use it on another system as a zip file. Java doesn't need to explicitly register the DLLs because it loads them dynamically as needed.

Related

need help figuring out why Im getting an exception on axlPort.getPhone(axlParams) call

I am attempting to run the axl demo shown at 'https://developer.cisco.com/docs/axl/#!javajax-ws-quickstart'
I am a newbie to axl, eclipse, and java, and just trying to get my toes wet.
I have followed the instructions listed and the project only shows 1 error at line:
GetPhoneRes getPhoneResponse = axlPort.getPhone(axlParams);
The error type says AXL Error.
There are no other errors showing in the compiler.
Can anyone give me any ideas of what the problem could be, or how to chase it?
package com.cisco.axl.demo;
/**
* demo to pull basic phone info
*/
import javax.xml.ws.BindingProvider;
import com.cisco.axlapiservice.AXLAPIService;
import com.cisco.axlapiservice.AXLPort;
import com.cisco.axl.api._10.*;
/**
*
** #author t01136
** Performs Getphone using AXL API
** Service Consumers were generated by the java ?? wsimport command:
** wsimport -keep -b schema/current/AXLSOAP.xsd -Xnocompile -s src -d bin -verbose schema/current/AXLAPI.wsd
* and since AXL uses HTTPS, you will have to install the UC applications
* certificate into you keystore in order to run this sample app.
* You can run the program by CD'ing to the bin folder within this project
* C:\Users\t01136.POS\eclipse-workspace\axl-demo\bin
* and running the following command
* java -cp . com.cisco.axl.demo.Demo
*/
public class Demo {
/**
* UC app host.
*/
protected static String ucHost = null;
/**
* OS admin.
*/
protected static String ucAdmin = null;
/**
* OS admin password.
*/
protected static String ucPswd = null;
/**
* phoneName used in request.
*/
protected static String phoneName = null;
/**
* Run the demo
*
* #param args not used
*/
public static void main(String[] args) {
// Verify JVM has a console
if (System.console() == null) {
System.err.println("The Cisco AXL Sample App requires a console.");
System.exit(1);
} else {
Demo.informUser("%nWelcome to the Cisco AXL Sample APP .%n");
}
Demo demo = new Demo();
demo.getPhoneInfo();
}
/**
* get information about phone
*/
public void getPhoneInfo() {
// Ask for the UC application to upgrade
// Demo.informuser("%nWhat UC server would you like to access?%n");
ucHost = promptUser(" Host: ");
ucAdmin = promptUser(" OS Admin Account: ");
ucPswd = promptUser(" OS Admin Password: ");
// Ask for the phone name
Demo.informUser("%nEnter the name of the phone you want to retrieve information about.%n");
phoneName = promptUser(" Phone Name: ");
// Make the getPhoneRequest
getPhone();
}
//private String promptUser(String string) {
// // TODO Auto-generated method stub
// return null;
// }
/**
* Makes the getPhone request and displays some of the fields that are returned.
*/
private void getPhone() {
// Instantiate the wsimport generated AXL API Service client --
// see the wsimport comments in the class javadocs above
AXLAPIService axlService = new AXLAPIService();
AXLPort axlPort = axlService.getAXLPort();
// Set the URL, user, and password on the JAX-WS client
String validatorUrl = "https://"
+ Demo.ucHost
+ ":8443/axl/";
((BindingProvider) axlPort).getRequestContext().put(
BindingProvider.ENDPOINT_ADDRESS_PROPERTY, validatorUrl);
((BindingProvider) axlPort).getRequestContext().put(
BindingProvider.USERNAME_PROPERTY, Demo.ucAdmin);
((BindingProvider) axlPort).getRequestContext().put(
BindingProvider.PASSWORD_PROPERTY, Demo.ucPswd);
// Create a GetPhoneReq object to represent the getPhone request and set the name of the device
//to name entered by user
GetPhoneReq axlParams = new GetPhoneReq();
axlParams.setName(phoneName);
//Make a call to the AXL Service and pass the getPhone request
GetPhoneRes getPhoneResponse = axlPort.getPhone(axlParams);
//display information returned in the response to the user
Demo.informUser("Product=" + getPhoneResponse.getReturn().getPhone().getProduct() + "%n"
+ getPhoneResponse.getReturn().getPhone().getLoadInformation().getValue() + "%n");
}
// -------------------- Some I/O Helper Methods ------------------------
/**
* Provide the user some instructions.
*/
protected static void informUser(String info) {
System.console().format(info);
}
/**
* Ask the user a question
*/
protected static String promptUser(String question) {
String answer = null;
while (answer==null || answer.isEmpty() ) {
answer = System.console().readLine(question);
}
return answer.trim();
}
}
Actually I have also noticed
That contained the following code:
package com.cisco.axlapiservice;
import javax.xml.ws.WebFault;
/**
* This class was generated by the JAX-WS RI.
* JAX-WS RI 2.1.6 in JDK 6
* Generated source version: 2.1
*
*/
#WebFault(name = "axlError", targetNamespace = "http://www.cisco.com/AXL/API/10.5")
public class AXLError
extends Exception
{
/**
* Java type that goes as soapenv:Fault detail element.
*
*/
private com.cisco.axl.api._10.AXLError faultInfo;
/**
*
* #param message
* #param faultInfo
*/
public AXLError(String message, com.cisco.axl.api._10.AXLError faultInfo) {
super(message);
this.faultInfo = faultInfo;
}
/**
*
* #param message
* #param faultInfo
* #param cause
*/
public AXLError(String message, com.cisco.axl.api._10.AXLError faultInfo, Throwable cause) {
super(message, cause);
this.faultInfo = faultInfo;
}
/**
*
* #return
* returns fault bean: com.cisco.axl.api._10.AXLError
*/
public com.cisco.axl.api._10.AXLError getFaultInfo() {
return faultInfo;
}
}
and when I look at the contents of 'getFaultInfo():AXLError' I see 'The serializable class AXLError does not declare a static final serialVersionUID field of type long', with 4 quick-fixes available.
But since all of that was part of the download from callmanager, I wouldnt think there would be an error in it.
Perhaps this will give someone a clue.
thanks

How do I get the os name from the client program?

There are parts of the program that are affected by OS type.
so i try to branch by os name as below.
when I run it locally,it works. but I run it as a client program after uploading it to the server, it seems that it can not get the os name.
Please let me know how can i get the os name from the client program.
thanks.
public void getOSName() {
String osName = System.getProperty("os.name")
if(!osName.trim().toUpperCase().equals("WINDOWS 10")){
run();
}else{
}
}
Checkout below util class for OS validation.
Using System properties : Due to this issue this approach may fail. Please see Java's “os.name” for Windows 10?
/**
* The Class OSValidator.
*/
public final class OSValidator {
/** The Constant OS. */
public static final String OS = System.getProperty("os.name").toLowerCase();
/**
* Checks if is windows 7.
*
* #return true, if is windows 7
*/
public static final boolean isWindows7() {
return (OS.indexOf("windows 7") >= 0);
}
/**
* Checks if is windows 10.
*
* #return true, if is windows 10
*/
public static final boolean isWindows10() {
return (OS.indexOf("windows 10") >= 0);
}
/**
* Checks if is mac.
*
* #return true, if is mac
*/
public static final boolean isMac() {
return (OS.indexOf("mac") >= 0);
}
}
Using SystemUtils – Apache Commons Lang
public String getOperatingSystemSystemUtils() {
String os = SystemUtils.OS_NAME;
// System.out.println("Using SystemUtils: " + os);
return os;
}

Upload File (image or video) from JSP to google cloud storage via Google app engine(JAVA)

I have Google App Engine (JAVA) server and Google Cloud Storage.
In my server there is a JSP file with upload file form (the user pick file from his computer).
What I need to do is send the file to some servlet and then the servlet will upload the file to google cloud storage. I cannot upload the file directly from the JSP page. I need that this action will be from the servlet, in the server side.
I tried so many thing that i dont know what to paste to here. I could upload a file to google cloud storage(GCS), but the GCS dont know what is the type of the file and cannot open it. I used the example here: https://github.com/GoogleCloudPlatform/google-cloud-java/tree/master/google-cloud-storage
How do I write the servlet and the jsp right ?
This is my code for file uploads.
public boolean uploadFile(String filePath, byte[] file) {
try {
setDefaultStorageCredentials();
storage.create(BlobInfo.newBuilder(bucketName, filePath).build(),
new ByteArrayInputStream(file));
return true;
} catch (Exception e) {
return false;
}
}
As long as the filename includes the file extension, you should not face any issues.
This is my implementation class:
import com.google.auth.Credentials;
import com.google.auth.oauth2.ServiceAccountCredentials;
import com.google.cloud.storage.Blob;
import com.google.cloud.storage.BlobInfo;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.TimeUnit;
/**
* Uploads a file to Google Cloud Storage to the bucket specified in the
* BUCKET_NAME environment variable, appending a timestamp to end of the
* uploaded filename.
*
* #throws IOException
* #throws FileNotFoundException
*/
#SuppressWarnings("static-access")
public class GoogleCloudStorage {
Variables variables = new Variables();
public GoogleCloudStorage() {
setDefaultStorageCredentials();
}
private static Storage storage = null;
private static Credentials credentials = null;
//Project Id can be obtained from your GCP console dashboard.
private static String projectId = "Your project Id";
//Create the bucket using the REST API or manually using the Google Cloud Storage Browser Interface.
private static String bucketName = "Your bucket name";
//Following 4 parameters can be obtained from the Private Key file.
//Client Id will usually be a numeric string
private static String clientId = "Your Client Id From the Key File.";
//Client Email Id is the email Id generated when you create the service account. This will be in the format of: *.iam.gserviceaccount.com
private static String clientEmailId = "Your Client Email Id From the Key File.";
//Private key can be obtained from the key file. This will be a very long string within the file. Paste the entire string here.
private static String privateKey = "Your Private Key From the Key File.";
//Private Key Id can be obtained from the key file. This is ususally a numeric string.
private static String privateKeyId = "Your Client Id From the Key File.";
/**
* This method sets the storage credentials for the default storage object.
*/
private void setDefaultStorageCredentials() {
try {
credentials = ServiceAccountCredentials.fromPkcs8(clientId, clientEmailId, privateKey, privateKeyId, null);
storage = StorageOptions.newBuilder()
.setCredentials(credentials)
.setProjectId(projectId).build().getService();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Uploads a given file to Google Cloud Storage.
*
* #param filePath The desired file path for the file to be uploaded. File path should be absolute path and should include folders, sub-folders, and file name
* #param file The file to be uploaded in byte array format
* #return true if the file has been successfully uploaded; false otherwise
*/
public boolean uploadFile(String filePath, byte[] file) {
try {
setDefaultStorageCredentials();
storage.create(BlobInfo.newBuilder(bucketName, filePath).build(),
new ByteArrayInputStream(file));
return true;
} catch (Exception e) {
return false;
}
}
/**
* Downloads a given file from Google Cloud Storage.
*
* #param filePath The desired file path for the file to be downloaded. File path should be absolute path and should include folders, sub-folders, and file name
* #return the downloaded file in byte array format
*/
public byte[] downloadFile(String filePath) throws FileNotFoundException, IOException {
setDefaultStorageCredentials();
return storage.get(bucketName).get(filePath).getContent();
}
/**
* Generates a temporary link to a file in Google Cloud Storage.
* This will allow temporary access to the file without actually exposing the file.
* Users accessing this link need not sign in using any credentials.
* <p>
* After the expiry time, this link will be expired and general public cannot access the file.
*
* #param filePath The desired file path for the file to be uploaded. File path should be absolute path and should include folders, sub-folders, and file name
* #return String containing the signed url for the file specified.
*/
public String getTemporaryFileLink(String filePath) throws Exception{
setDefaultStorageCredentials();
Blob blob = storage.get(bucketName).get(filePath);
String blobName = blob.getName();
URL signedUrl = storage.signUrl(BlobInfo.newBuilder(bucketName, blobName).build(), 5,TimeUnit.MINUTES);
return signedUrl.toExternalForm();
}
/**
* Deletes a given file from Google Cloud Storage.
*
* #param filePath The desired file path for the file to be deleted. File path should be absolute path and should include folders, sub-folders, and file name
* #return true if the file has been successfully deleted; false otherwise
*/
public boolean deleteFile(String filePath){
setDefaultStorageCredentials();
return storage.delete(storage.get(bucketName).get(filePath).getBlobId());
}
}
Reference: Google Cloud Storage Wrapper

Building effective model with DefaultModelBuilder . build()

I'm trying to get a effective model for a project and currently under the Maven Core API 3.0.3 (or 3.0.4) there's this method called build() which is neat BUT..
it requires too much like ModelNormalizer, ProfileInjector etc for it not to throw null pointer exception while building. There's so much things that need initialization before I can build the effective model and all the information I have is a filepath to the pom.xml
Anyone has work this out?
Here is sample code:
DefaultModelBuilder modelBuilder = new DefaultModelBuilderFactory().newInstance();
ModelBuildingRequest req = new DefaultModelBuildingRequest();
req.setProcessPlugins(false);
req.setPomFile(file);
req.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL);
req.setModelResolver(new MyLocalModelResolver());
Model model = modelBuilder.build(req).getEffectiveModel();
Maybe this library can help: https://github.com/jenkinsci/lib-jenkins-maven-embedder
Or at least as a sample.
hth
Olivier
Yes it works for me. I have to set all data with default values. Very annoying...
I have created a MavenModelBuilder builder class for that
/**
* Default MavenModelBuilder.
*/
public class MavenModelBuilder extends DefaultModelBuilder {
/**
* Constructor
*/
public MavenModelBuilder() {
super();
ModelProcessor modelProcessor = new DefaultModelProcessor()
.setModelLocator(new DefaultModelLocator())
.setModelReader(new DefaultModelReader());
ModelInterpolator modelInterpolator = new StringSearchModelInterpolator()
.setPathTranslator(new DefaultPathTranslator())
.setUrlNormalizer(new DefaultUrlNormalizer());
setProfileSelector(new DefaultProfileSelector());
setModelProcessor(modelProcessor);
setModelValidator(new DefaultModelValidator());
setSuperPomProvider(new DefaultSuperPomProvider().setModelProcessor(modelProcessor));
setModelNormalizer(new DefaultModelNormalizer());
setInheritanceAssembler(new DefaultInheritanceAssembler());
setModelInterpolator(modelInterpolator);
setModelUrlNormalizer(new DefaultModelUrlNormalizer().setUrlNormalizer(new DefaultUrlNormalizer()));
setModelPathTranslator(new DefaultModelPathTranslator().setPathTranslator(new DefaultPathTranslator()));
setPluginManagementInjector(new DefaultPluginManagementInjector());
setLifecycleBindingsInjector(new DefaultLifecycleBindingsInjector());
setDependencyManagementInjector(new DefaultDependencyManagementInjector());
setReportConfigurationExpander(new DefaultReportConfigurationExpander());
setReportingConverter(new DefaultReportingConverter());
setPluginConfigurationExpander(new DefaultPluginConfigurationExpander());
setDependencyManagementImporter(new DefaultDependencyManagementImporter());
setProfileInjector(new DefaultProfileInjector());
}
}
And i call it like this
/**
* Parse the xml file to get the model of the xml file.
*
* #param path of the project
* #throws IllegalArgumentException : exception
*/
public static Model parseFile(String path) throws IllegalArgumentException {
DefaultModelBuilder builder = new MavenModelBuilder();
ModelBuildingRequest req = new DefaultModelBuildingRequest();
req.setProcessPlugins(false);
req.setPomFile(new File(path));
req.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL);
Model model = null;
try {
model = builder.build(req).getEffectiveModel();
} catch (ModelBuildingException e) {
e.printStackTrace();
}
return model;
}

How can I change the running directory of a program - by setting it in the exe shortcut?

I have an exe process that is running with a shortcut.
In the "Start in" property of the shortcut I set it to the folder where all app resources are. The process still looks for files at the location of the exe and not the location written in the shortcut.
I can also see it in Process Explorer - the "current directory" is the location of the exe.
Is there a way to change it?
(If I wasn't clear enough -
I want to put my app in a central network location and not in each user folder - but I want it to run - above each user folder by putting a shortcut in each user folder.)
BTW : Why don't I solve it with code writing? Because of third party jars I have in my exe (I am using exe4j to make an exe)
From exe4-j documentation.., it seems this can be configured in exe4j project.
Working directory
For some applications (especially GUI applications) you might want to change the working directory
to a specific directory relative to the executable, for example to read config files that are in a fixed
location. To do so, please select the Change working directory to: checkbox and enter a
directory relative to the executable in the adjacent text field. To change the current directory to the
same directory where the executable is located, please enter a single dot.
One alternative is to use a System Property. Just create a shortcut like this:
java -Dmyproperty="\\myserver\myfolder" -jar yourjar.jar
And get this property on your program:
System.getProperty("myproperty");
You can also set multiple System Properties.
I would start the java application via a cmd or bat file, then change to the work dir before you call javaw. If you don't do any thing special in your java application code all the paths in it will be relative to the place where you started java.
Jess
You can hack the classpath programatically which would allow you to specify a specific folder or series of folders to access the data.
import java.io.IOException;
import java.io.File;
import java.net.URLClassLoader;
import java.net.URL;
import java.lang.reflect.Method;
public class ClassPathHacker {
private static final Class[] parameters = new Class[]{URL.class};
public static void addFile(String s) throws IOException {
File f = new File(s);
addFile(f);
}//end method
public static void addFile(File f) throws IOException {
addURL(f.toURI().toURL());
}//end method
public static void addURL(URL u) throws IOException {
URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Class sysclass = URLClassLoader.class;
try {
Method method = sysclass.getDeclaredMethod("addURL", parameters);
method.setAccessible(true);
method.invoke(sysloader, new Object[]{u});
} catch (Throwable t) {
t.printStackTrace();
throw new IOException("Error, could not add URL to system classloader");
}//end try catch
}//end method
}//end class
with the property loader file of
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Properties;
import java.util.ResourceBundle;
public abstract class PropertyLoader
{
/**
* Looks up a resource named 'name' in the classpath. The resource must map
* to a file with .properties extention. The name is assumed to be absolute
* and can use either "/" or "." for package segment separation with an
* optional leading "/" and optional ".properties" suffix. Thus, the
* following names refer to the same resource:
* <pre>
* some.pkg.Resource
* some.pkg.Resource.properties
* some/pkg/Resource
* some/pkg/Resource.properties
* /some/pkg/Resource
* /some/pkg/Resource.properties
* </pre>
*
* #param name classpath resource name [may not be null]
* #param loader classloader through which to load the resource [null
* is equivalent to the application loader]
*
* #return resource converted to java.util.Properties [may be null if the
* resource was not found and THROW_ON_LOAD_FAILURE is false]
* #throws IllegalArgumentException if the resource was not found and
* THROW_ON_LOAD_FAILURE is true
*/
public static Properties loadProperties (String name, ClassLoader loader)
{
if (name == null)
throw new IllegalArgumentException ("null input: name");
if (name.startsWith ("/"))
name = name.substring (1);
if (name.endsWith (SUFFIX))
name = name.substring (0, name.length () - SUFFIX.length ());
Properties result = null;
InputStream in = null;
try
{
if (loader == null) loader = ClassLoader.getSystemClassLoader ();
if (LOAD_AS_RESOURCE_BUNDLE)
{
name = name.replace ('/', '.');
// Throws MissingResourceException on lookup failures:
final ResourceBundle rb = ResourceBundle.getBundle (name,
Locale.getDefault (), loader);
result = new Properties ();
for (Enumeration keys = rb.getKeys (); keys.hasMoreElements ();)
{
final String key = (String) keys.nextElement ();
final String value = rb.getString (key);
result.put (key, value);
}
}
else
{
name = name.replace ('.', '/');
if (! name.endsWith (SUFFIX))
name = name.concat (SUFFIX);
// Returns null on lookup failures:
in = loader.getResourceAsStream(name);
if (in != null)
{
result = new Properties ();
result.load (in); // Can throw IOException
}
}
}
catch (Exception e)
{
result = null;
}
finally
{
if (in != null) try { in.close (); } catch (Throwable ignore) {}
}
if (THROW_ON_LOAD_FAILURE && (result == null))
{
throw new IllegalArgumentException ("could not load [" + name + "]"+
" as " + (LOAD_AS_RESOURCE_BUNDLE
? "a resource bundle"
: "a classloader resource"));
}
return result;
}
/**
* A convenience overload of {#link #loadProperties(String, ClassLoader)}
* that uses the current thread's context classloader.
*/
public static Properties loadProperties (final String name)
{
return loadProperties (name,
Thread.currentThread ().getContextClassLoader ());
}
private static final boolean THROW_ON_LOAD_FAILURE = true;
private static final boolean LOAD_AS_RESOURCE_BUNDLE = false;
private static final String SUFFIX = ".properties";
} // End of class
then you can add a path as follows
try {
//First Load up the properties and populate the config
ClassPathHacker.addFile("/pathtomyapp");
} catch (IOException ex) {
ex.printStackTrace();
}
properties = PropertyLoader.loadProperties("myapp");
or you can also use getResourceBundle to get your resources, this is just one example of hacking the classpath to allow files to be available, you can always just add the classpath programatically and let the jar files you need to be available to reside there, so if you always ensure that the app network path is Q: you can add Q:\ to the classpath.

Categories

Resources