I am trying to build a command parser which receives a block of data and parses that data into an instance of a specific command. This is basically then a factory whereby the instance returned from the factory is based on a key.
So more specifically, say a receive a block of raw binary data:
0x02 0x23 0x01 0x00 0x00 0x1f
And the 3rd byte in this stream defines the command, I want to create an instance of CommandOne. Obviously there will be additional methods to handle parsing the rest of the data according to the command, but the first step is getting that instance of the command from the command number. This where I say this is a factory using a key.
There are a lot of discussions on how to build factories in java, some very direct, some using various bits of generics and reflections; but I have had no luck finding a specific implementation that fits what I am trying to accomplish. I did however find bits and pieces that relate to what I am trying to accomplish and so I have put those together into an answer which is the first response below. Is this a good response or am I overlooking something simpler or something more complete?
The following is a generic form of the solution. This is all built into a single package containing all the commands and the factory. Note that adding a new command does not require any changes to the factory itself.
This is the abstract class which all commands must implement. It also contains the factory method getInstance.
public abstract class Commands
{
private static Map<Integer,Constructor<?>> commandConstructorMap = null;
private static void loadMap()
{
commandConstructorMap = new HashMap<Integer,Constructor<?>>();
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if(classLoader == null) return;
String myPathName = Commands.class.getName();
String myPath[] = myPathName.split("\\.");
if(myPath == null || myPath.length <= 1) return;
int pkgLen = myPath.length - 1;
StringBuilder pkgNm = new StringBuilder();
pkgNm.append(myPath[0]);
for(int i=1;i<pkgLen;i++)
pkgNm.append(".").append(myPath[i]);
String packageName = pkgNm.toString();
String path = packageName.replace('.', '/');
Enumeration<URL> resources;
try
{
resources = classLoader.getResources(path);
}
catch(IOException ioe)
{
return; // failure, just leave constructor empty
}
List<File> dirs = new ArrayList<File>();
while(resources.hasMoreElements())
dirs.add(new File(resources.nextElement().getFile()));
for(File dir:dirs)
{
if(!dir.exists() || !dir.isDirectory()) continue;
File[] files = dir.listFiles();
for(File file:files)
{
if(!file.isFile()) continue;
String fileName = file.getName();
if(!fileName.endsWith(".class")) continue;
try
{
String className = packageName+'.'+fileName.substring(0, fileName.length()-6);
Class<?> clazz = Class.forName(className);
Constructor<?> cons = clazz.getConstructor();
Object instance = cons.newInstance();
if(instance instanceof Commands)
{
commandConstructorMap.put(new Integer(((Commands) instance).getCommand()),cons);
}
}
catch(Exception e){} // do nothing special for exception, just don't add to map
}
}
}
public static Commands getInstance(Integer command) throws Exception
{
if(commandConstructorMap == null)
{
loadMap();
}
if(commandConstructorMap.containsKey(command))
return (Commands)commandConstructorMap.get(cmd).newInstance();
throw new Exception();
}
abstract Integer getCommand();
}
Note the return type of the abstracted getCommand is the same as the type used as the key, this is the relationship conrtol and can be almost any desired object type. One caveat of this mechanism is that this does create and ultimately discard one instance of every command object, but it does this only once, future calls will only create a single instance of the class indicated by the key.
This is an example of one of the command file implementations, obviously there would need to be other code related to building all the specifics of that command, the goal here is just to demonstrate how to build the part of the command class that is utilized in the factory.
public class CommandOne
extends Commands
{
Integer getCommand()
{
return new Integer(1);
}
}
And finally a demonstration of how this works
public static void main(String[] args)
{
try
{
Commands cmd = Commands.getInstance(new Integer(1));
if(cmd instanceof CommandOne)
System.out.println("Command using key 1 is: "+cmd.getClass().getSimpleName());
cmd = Commands.getInstance(new Integer(2));
if(cmd instanceof CommandTwo)
System.out.println("Command using key 2 is: "+cmd.getClass().getSimpleName());
cmd = Commands.getInstance(new Integer(3));
if(cmd instanceof CommandThree)
System.out.println("Command using key 3 is: "+cmd.getClass().getSimpleName());
}
catch(Exception e)
{
System.out.println("Command instantiation failed");
}
}
The results of running this (assuming there are definitions for commands CommandTwo and CommandThree as well as the demonstrated CommandOne) would be something like this:
Command using key 1 is: CommandOne
Command using key 2 is: CommandTwo
Command using key 3 is: CommandThree
Related
Hi I can't figure out how to verify if a user belong to one o more group under Linux os using java 7 nio library.
Can anyone help me about this issue?
You can try to read the file /etc/group.
I have developed a class to easily query this file:
public class UserInfo {
public UserInfo() throws FileNotFoundException, IOException {
this.group2users = new HashMap<>();
FileReader fileReader = new FileReader(groupsFilePath);
BufferedReader groupsReader = new BufferedReader(fileReader);
while(groupsReader.ready())
{
try
{
String line = groupsReader.readLine();
String [] tokens = line.split(":");
String groupName = tokens[0];
Set<String> users = group2users.get(groupName);
if(users == null)
{
users = new HashSet<String>();
group2users.put(groupName, users);
}
if(tokens.length>3)
{
for(String uStr: tokens[3].split(","))
users.add(uStr);
}
} catch (Exception e) { continue; }
}
groupsReader.close();
fileReader.close();
}
public boolean belongs2group(String user, String group)
{
Set<String> groupRef = group2users.get(group);
if(groupRef == null) return false;
return groupRef.contains(user);
}
private String groupsFilePath = "/etc/group";
private Map<String, Set<String>> group2users;
}
This code maps the /etc/group file and keep a map of groups-their users set.
I have developed just one query method (belongs2group) but it is fairly easy to add methods to list all groups and/or all users.
This code is written using the old-fashioned-mainstream java io-api but I think it can be easily adapted to nio. Let me know if you need me to complete that step.
I do not think that reading local /etc/passwd or /etc/group could be good idea, because nis/ldap/ipa/pam can introduce other sources of infromation about group membership.
So, it depends on you environment and some other details. E.g.:
Groups for logged in (current) user
com.sun.security.auth.module.UnixSystem().getGroups()
Hadoop
org.apache.hadoop.security.UserGroupInformation.getBestUGI(null,"root").getGroupNames()
If neither is you case
You can create jna wrapper for getgroups(2).
Or improve UnixSystem and Java_com_sun_security_auth_module_UnixSystem_getUnixInfo from jdk to take user id/name parameter.
Or rewrite some implementation of org.apache.hadoop.security.GroupMappingServiceProvider interface to not depend on hadoop environment.
I have an executable jar that runs a Java Swing application with an internal SqlLite db.
Users (by mistake) do more than a click on the jar, causing the db lock.
I'd like to prevent this behavior.
What can I do?
thank you very much
You need some kind of synchronization mechanism.
Either you need to code it yourself, or you can create a Java WebStart configuration for your application, where Java WebStart can handle the "only one invocation" through the Single Instance Service (which you must call explicitly in your code).
See http://docs.oracle.com/javase/6/docs/technotes/guides/javaws/developersguide/examples.html#SingleInstanceService for an example.
The first instances accessing the db should acquire a lock of some sort on the db and all further instances should first check if there is already such a lock. If there is one -> "I am not the first, show warning/error, quit.", if there is none "I am the first, get a lock, proceed."
You can use JPS or JNI (need to implement on different platform). The attached is the JPS code to check the Java application instance. You can modify it to more OO.
Using File, Socket or Registry as a lock is not perfect, since there are a lot of chance that a mis-operation can make your application can not start any more (for example, another program occupe the same port)
import java.io.*;
public class TestRun {
public TestRun() {}
public static void main(String args[]) {
String jpsApp = "jps -mlvV";
int count = 0;
try {
Process p = Runtime.getRuntime().exec(jpsApp);
//parser the result to check if TestAPP is running
InputStream is = p.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println();
System.out.println(line);
String[] pair = line.split(" ");
if (pair.length >= 2) {
System.out.println("name is " + pair[1]);
if (pair[1].trim().indexOf("TestRun") > -1) {
count++;
System.out.println("count is " + count);
}
}
}
//it is running, just exit the second instance
if(count>1){
System.out.println("Has run a application!");
return;
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
I seem to be having what I believe is a ClassLoader problem using db4o with NetBeans. When I run the exact same code from the terminal with the same jar files from .../jre/lib/ext, everything works fine. The issue is that when I make a native query on some Classes that are loaded at runtime using a ClassLoader, I get an empty List from the database where I should definitely be getting a List with some elements (as I said, the same code works fine from the command line). I feel like this may be because the NetBeans ClassLoader works differently than the JVM ClassLoader, but I don't know, I'm certainly no expert on either. Here is the code from my main function.....
////////////////////////////////////////////////////////////////////////////////////////////
package gql;
import java.io.*;
import java.util.*;
import com.db4o.*;
public class GQL {
////////////////////////////////////////////////////////////////////////////
// GLOBAL VARIABLES
////////////////////////////////////////////////////////////////////////////
private static ObjectSet dbObjects;
private static LinkedList classes = new LinkedList();
private static String dbPath, classPath;
private static ObjectContainer db;
private static ClassLoader coreClassLoader =
ClassLoader.getSystemClassLoader();
private static ClassLoader subClassLoader =
ClassLoader.getSystemClassLoader();
public static void main(String[] args) {
////////////////////////////////////////////////////////////////////////
// CREATE DATABASE OBJECT
////////////////////////////////////////////////////////////////////////
// If no path to a database is provided on the command line, print
// error and exit program
if (args.length < 1) {
System.err.println("\nError: no database path provided.\n");
return;
} else if (args.length > 1) {
dbPath = args[0];
// TODO - dubug command line classpath
classPath = args[1];
db = Db4o.openFile(dbPath);
} else { // We assume that the database Classes are stored somewhere
dbPath = args[0]; // along the CLASSPATH, and therefore classPath
classPath = ""; // can be left empty
db = Db4o.openFile(dbPath);
}
System.out.print("GQL> ");
// The prompt of the interpreter is within a do-while loop, which can
// be terminated by entering "exit"
do {
try {
/////////////////////////////////////////////////////////////////
// READ IN QUERY FILE
/////////////////////////////////////////////////////////////////
// We create a Scanner object to read tokens from the standard in
// stream - these will be our DLOG files provided by the user
Scanner fileScanner = new Scanner(System.in);
String GQLFile = fileScanner.next();
// Break loop and exit program if user enters "exit"
if (GQLFile.equalsIgnoreCase("exit")) {
break;
// If the user input is not preceeded by "#" and teminated with
// ";" then the input is invalid - the user is prompted again
} else if (!(GQLFile.substring(0,1).equals("#")) ||
!(GQLFile.substring(GQLFile.length()-1,
GQLFile.length()).equals(";"))) {
System.out.println("\nInvalid input.\nUsage: "
+ " #filename;\n");
System.out.print("GQL> ");
continue;
} else {
// Parse out the "#" and ";" from the user's input and send
// this to a file Reader object
GQLFile = GQLFile.substring(1,GQLFile.length()-1);
}
// Now we create a reader object and give it the user's parsed
// input - in the event of a FileNotFoundException, the user is
// prompted again
Reader reader;
try {
reader = new FileReader(GQLFile);
} catch (FileNotFoundException e) {
System.out.println("\nFile " + GQLFile +
" does not exist.\n");
System.out.print("GQL> ");
continue;
}
/////////////////////////////////////////////////////////////////
// PARSE QUERY
/////////////////////////////////////////////////////////////////
// The parser and Lexer objects are created in the parser.java
// and Lexer.java files, respectively - The parser takes the
// Lexer as an argument - the value variable generated by the
// parse() method will return the topmost grammar construct,
// which in this case is a Query object
parser p = new parser(new Lexer(reader));
Query query = (Query) p.parse().value;
/////////////////////////////////////////////////////////////////
System.out.println("\n----------------------------Input Query-----" +
"-----------------------\n");
System.out.println("\n SUCCESSFUL PARSE " +
" \n");
System.out.println("--------------------------------------" +
"------------------------------\n");
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
// LOAD ALL CLASSES USED IN DATABASE INTO RUNTIME
/////////////////////////////////////////////////////////////////
// databse Classes should be kept on the CLASSPATH, or the path
// to these classes should be provided as a second command line
// argument
boolean coreClassesLoaded = loadCoreClasses(coreClassLoader,
classPath);
if (!coreClassesLoaded) {
System.err.println("\nError: one or more of core Classes"
+ "Node, Egge and SimplePath could not be found.\n");
db.close();
return;
}
//
System.out.println("Core classes loaded.\n");
boolean subclassesLoaded = query.loadSubclasses(subClassLoader,
classPath);
if (!subclassesLoaded) {
System.err.println("\nError: subclasses could not be" +
" loaded.\n");
db.close();
return;
}
//
System.out.println("Subclasses loaded.\n");
/////////////////////////////////////////////////////////////////
// MAKE SURE THE DATABASE ACTUALLY CONTAINS SOME OBJECTS AND,
// IF SO, PUT AN INSTANCE OF EACH CLASS REPRESENTED INTO THE
// LINKEDLIST CLASSLIST - SINCE WE LOADED THE DATABASE CLASSES
// INTO THE RUNTIME ENVIRONMENT, OBJECTS RETURNED BY DATABASE
// QUERIES WILL REMAIN TRUE TO THEIR TYPE; IF WE HADN'T DONE
// THIS, THESE OBJECTS WOULD BE RETURNED AS TYPE GENERICOBJECT
/////////////////////////////////////////////////////////////////
dbObjects = db.queryByExample(Object.class);
if (dbObjects.hasNext()) {
query.addClassesToList(dbObjects, classes);
} else {
System.err.println("\nError: no objects in database.\n");
db.close();
return;
}
//
System.out.println(classes);
/////////////////////////////////////////////////////////////////
// SEMANTIC CHECKS //
/////////////////////////////////////////////////////////////////
boolean headArgsAreSet = query.setHeadArgClasses(classes);
if (!headArgsAreSet) {
db.close();
return;
}
boolean typesMatch = query.checkQueryTypes(db);
if (!typesMatch) {
db.close();
return;
}
/////////////////////////////////////////////////////////////////
// EVALUATION
/////////////////////////////////////////////////////////////////
query.evaluateQuery(db);
} catch (Exception e) {
System.out.println("\nSYNTAX ERROR\n");
e.printStackTrace();
}
System.out.print("GQL> ");
} while (true);
System.out.println("\nExiting...\n");
db.close();
}
private static boolean loadCoreClasses(ClassLoader coreClassLoader,
String classPath) {
try {
coreClassLoader.loadClass("Node");
coreClassLoader.loadClass("Edge");
coreClassLoader.loadClass("SimplePath");
} catch (ClassNotFoundException cnfe) {
return false;
}
return true;
}
}
////////////////////////////////////////////////////////////////////////////////////////////
The strange thing is, the classes I need are definitely getting loaded into the runtime environment, as I use them to set some Class member variables, for example in the "SEMANTIC CHECKS" section. So it's like the application can see the dynamically loaded Classes, but the db4o API/database cannot. Also, I have the Class jar and the db4o jar set up as Netbeans libraries, not just in .../jre/lib/ext. Here's a snippet of the code in the Class where I actually use the db4o native query that's giving me problems...
////////////////////////////////////////////////////////////////////////////////////////////
public void evaluateQuery(ObjectContainer db) {
if (this.hasPredicate) {
;
} else {
if (this.isNode) {
List nodes = db.query(new Predicate() {
#Override
public boolean match(Node node) {
return (node.getName().equals("5"));
}
});
System.out.println("\n_________________RESULT__________________________");
System.out.println("\nNode: " + nodes.get(0).getName()
//+ ".\n");
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////
... if I do the following instead I still get an empty List...
////////////////////////////////////////////////////////////////////////////////////////////
public void evaluateQuery(ObjectContainer db) {
if (this.hasPredicate) {
;
} else {
if (this.isNode) {
List nodes = db.queryByExample(Node.class);
System.out.println(nodes.size());
for (int i = 0; i < nodes.size(); i++) {
System.out.println("\nNode: " + nodes.get(i).getName());
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////
Hmm, I don't see any dynamic class loading problems here. You're using the system's classloader, which should be visible to db4o. You don't even need to load the classes, db4o will do that with the classloaders.
Are you sure that the application picks up the same database? Are you using a relative path?
Btw you can explicitly set the classloader for db4o, like this.
EmbeddedConfiguration configuration = Db4oEmbedded.newConfiguration();
JdkLoader classLookUp = new ClassLoaderLookup(
Thread.currentThread().getContextClassLoader(),
new URLClassLoader(new URL[]{new URL("file://./some/other/location")}));
configuration.common().reflectWith(new JdkReflector(classLookUp));
ObjectContainer container = Db4oEmbedded.openFile(configuration,"database.db4o");
Well it seems like this is a bug in Linux/Netbeans for Linux/Db4o. I used the exact same source files on a windows box and everything worked fine. I'm pretty disappointed, I don't want to have to use windows for this project. :/
I am not a good programmer. In school, I learned MATLAB. So i have no idea what I am doing.
I am working with the ThingMagic M6 reader. They have their own API. I wanted to create my own application to read the program. I want to use a sample program that they have supplied (since my program doesn't seem to work). However, the supplied program only accepts command line arguments. How do i change it so I can pass arguments to it in my code.
This is the supplied code: (at the command line I input tmr://10.0.0.101)
/**
* Sample program that reads tags for a fixed period of time (500ms)
* and prints the tags found.
*/
// Import the API
package samples;
import com.thingmagic.*;
public class read
{
static void usage()
{
System.out.printf("Usage: demo reader-uri <command> [args]\n" +
" (URI: 'tmr:///COM1' or 'tmr://astra-2100d3/' " +
"or 'tmr:///dev/ttyS0')\n\n" +
"Available commands:\n");
System.exit(1);
}
public static void setTrace(Reader r, String args[])
{
if (args[0].toLowerCase().equals("on"))
{
r.addTransportListener(r.simpleTransportListener);
}
}
static class TagReadListener implements ReadListener
{
public void tagRead(Reader r, TagReadData t) {
System.out.println("Tag Read " + t);
}
}
public static void main(String argv[])
{
System.out.println(argv.getClass().toString());
// Program setup
TagFilter target;
Reader r;
int nextarg;
boolean trace;
r = null;
target = null;
trace = false;
nextarg = 0;
if (argv.length < 1)
usage();
if (argv[nextarg].equals("-v"))
{
trace = true;
nextarg++;
System.out.println("Trace");
}
// Create Reader object, connecting to physical device
try
{
TagReadData[] tagReads;
r = Reader.create(argv[nextarg]);
if (trace)
{
setTrace(r, new String[] {"on"});
}
r.connect();
if (Reader.Region.UNSPEC == (Reader.Region)r.paramGet("/reader/region/id"))
{
r.paramSet("/reader/region/id", Reader.Region.NA);
}
r.addReadListener(new TagReadListener() );
// Read tags
tagReads = r.read(500);
// Print tag reads
for (TagReadData tr : tagReads)
System.out.println(tr.toString());
// Shut down reader
r.destroy();
}
catch (ReaderException re)
{
System.out.println("Reader Exception : " + re.getMessage());
}
catch (Exception re)
{
System.out.println("Exception : " + re.getMessage());
}
}
}
This is me trying to use it: (arg comes from a JTextField)
String[] argv = new String[1];
argv[0] = arg;
readOnceApp(argv);
I have a feeling there is a really simple answer to this problem, I just can't figure it out. I searched the internet for a few days and read books, and still can't figure it out. Any help is appreciated. Thank You.
edit: readOnceApp is one method I wrote. It is basically just the main method of the supplied code. I can include it, if it will help. I just didn't want to post too much code.
If you want to call the "main" method of a class from another class, do it like this:
String [] args = new String [1];
args[0]= "some param";
readOnceApp.main(args);
This is making the assumption that "readOnceApp" is the name of your class. (BTW, you should follow the convention of using capitalized class names, e.g. ReadOnceApp).
Hope this helps.
Here is code:
import java.awt.*;
import java.util.*;
import javax.media.*;
import javax.media.protocol.*;
import javax.media.control.*;
import javax.media.format.*;
public class jmfcam05v
{
DataSource dataSource;
PushBufferStream pbs;
Vector camImgSize = new Vector();
Vector camCapDevice = new Vector();
Vector camCapFormat = new Vector();
int camFPS;
int camImgSel;
Processor processor = null;
DataSink datasink = null;
public static void main(String[] args)
{
jmfcam05v jmfcam = new jmfcam05v();
}
public jmfcam05v()
{
fetchDeviceFormats();
camFPS = 30; // framerate
fetchDeviceDataSource();
createPBDSource();
createProcessor(dataSource);
startCapture();
try{Thread.sleep(20000);}catch(Exception e){} // 20 seconds
stopCapture();
}
boolean fetchDeviceFormats()
{
Vector deviceList = CaptureDeviceManager.getDeviceList(new VideoFormat(null));
CaptureDeviceInfo CapDevice = null;
Format CapFormat = null;
String type = "N/A";
CaptureDeviceInfo deviceInfo=null;boolean VideoFormatMatch=false;
for(int i=0;i<deviceList.size();i++)
{
// search for video device
deviceInfo = (CaptureDeviceInfo)deviceList.elementAt(i);
if(deviceInfo.getName().indexOf("vfw:")<0)continue;
Format deviceFormat[] = deviceInfo.getFormats();
for (int f=0;f<deviceFormat.length;f++)
{
if(deviceFormat[f] instanceof RGBFormat)type="RGB";
if(deviceFormat[f] instanceof YUVFormat)type="YUV";
if(deviceFormat[f] instanceof JPEGFormat)type="JPG";
Dimension size = ((VideoFormat)deviceFormat[f]).getSize();
camImgSize.addElement(type+" "+size.width+"x"+size.height);
CapDevice = deviceInfo;
camCapDevice.addElement(CapDevice);
//System.out.println("Video device = " + deviceInfo.getName());
CapFormat = (VideoFormat)deviceFormat[f];
camCapFormat.addElement(CapFormat);
//System.out.println("Video format = " + deviceFormat[f].toString());
VideoFormatMatch=true; // at least one
}
}
if(VideoFormatMatch==false)
{
if(deviceInfo!=null)System.out.println(deviceInfo);
System.out.println("Video Format not found");
return false;
}
return true;
}
void fetchDeviceDataSource()
{
CaptureDeviceInfo CapDevice =
(CaptureDeviceInfo)camCapDevice.elementAt(camImgSel);
System.out.println("Video device = " + CapDevice.getName());
Format CapFormat = (Format)camCapFormat.elementAt(camImgSel);
System.out.println("Video format = " + CapFormat.toString());
MediaLocator loc = CapDevice.getLocator();
try
{
dataSource = Manager.createDataSource(loc);
}
catch(Exception e){}
try
{
FormatControl formCont=((CaptureDevice)dataSource).getFormatControls()[0];
VideoFormat formatVideoNew = new
VideoFormat(null,null,-1,null,(float)camFPS);
formCont.setFormat(CapFormat.intersects(formatVideoNew));
}
catch(Exception e){}
}
void createPBDSource()
{
try
{
pbs=((PushBufferDataSource)dataSource).getStreams()[0];
}
catch(Exception e){}
}
public void createProcessor(DataSource datasource)
{
FileTypeDescriptor ftd = new FileTypeDescriptor(FileTypeDescriptor.MSVIDEO);
Format[] formats = new Format[] {new VideoFormat(VideoFormat.INDEO50)};
ProcessorModel pm = new ProcessorModel(datasource, formats, ftd);
try
{
processor = Manager.createRealizedProcessor(pm);
}
catch(Exception me)
{
System.out.println(me);
// Make sure the capture devices are released
datasource.disconnect();
return;
}
}
private void startCapture()
{
// Get the processor's output, create a DataSink and connect the two.
DataSource outputDS = processor.getDataOutput();
try
{
MediaLocator ml = new MediaLocator("file:capture.mpg");
datasink = Manager.createDataSink(outputDS, ml);
datasink.open();
datasink.start();
}catch (Exception e)
{
System.out.println(e);
}
processor.start();
System.out.println("Started saving...");
}
private void pauseCapture()
{
processor.stop();
}
private void resumeCapture()
{
processor.start();
}
private void stopCapture()
{
// Stop the capture and the file writer (DataSink)
processor.stop();
processor.close();
datasink.close();
processor = null;
System.out.println("Done saving.");
}
}
Error:
run:
Video device = vfw:Microsoft WDM Image Capture (Win32):0
Video format = YUV Video Format: Size = java.awt.Dimension[width=640,height=480] MaxDataLength = 614400 DataType = class [B yuvType = 32 StrideY = 1280 StrideUV = 1280 OffsetY = 0 OffsetU = 1 OffsetV = 3
javax.media.CannotRealizeException: Unable to provide all requested tracks
Exception in thread "main" java.lang.NullPointerException
at jmfcam05v.startCapture(jmfcam05v.java:202)
at jmfcam05v.(jmfcam05v.java:82)
at jmfcam05v.main(jmfcam05v.java:64)
please help me with this error.i am using windows vista OS.
can anyone suggest me how to store files in .3gp format?please help
Exception in thread "main" java.lang.NullPointerException
at jmfcam05v.startCapture(jmfcam05v.java:202)
Some object reference at line 202 of jmfcam05v.java, inside the startCapture() method, is null while the code is trying to access/invoke it using the dot . operator.
E.g.
SomeObject someObject = null;
someObject.doSomething(); // NullPointerException.
The solution is actually easy. Just make sure that it's not null by either instantiating it:
if (someObject == null) {
someObject = new SomeObject();
}
someObject.doSomething(); // No NPE more!
... or by simply doing a nullcheck before accessing/invoking:
if (someObject != null) {
someObject.doSomething(); // No NPE more!
}
The NPE is easy. One of the lines
MediaLocator ml = new MediaLocator("file:capture.mpg");
datasink = Manager.createDataSink(outputDS, ml);
in method startCapture throws a CannotRealizeException. So datasink is not initialized and if you try to close it later in stopCapture, it's still null and that causes the NPE.
To avoid the NPE: test, if datasink isn't null before calling a method on it.
EDIT
and could you PLEASE remove the application logic from the constructor and move it to the main method. A constructor is for constructing an object, mainly for initializing class members and nothing else. And Java classes should start with a capital letter, that helps people (and us) understanding the code.
Poor exception handling is to blame here.
Most likely, the processor member isn't getting initialized. If there isn't a processor, it looks like you can't do anything useful. So let the exception fly, terminating your doomed program at that point, instead of "swallowing" it and blithely continuing on.
Also, if you are going to eat exceptions and soldier on, at least print them properly: ex.printStackTrace(), instead of System.out.println(ex).
But it would be much better to add throws clauses to your methods, and not catch any exceptions, since you cannot recover from them.
Perhaps the Indeo codec was present on your Windows XP box, but isn't available on your Vista machine. (Update: In fact, Indeo is not supported and not compatible with Vista.) That prevents the processor from being created successfully, and your program is doomed from that point. Is there a way to test whether a particular FileTypeDescriptor or VideoFormat is valid at runtime?
It looks as though this line:
processor = Manager.createRealizedProcessor(pm);
Throws a CannotRealizeException, causing processor to be null and leading to the NPE later on. As for what that exception is thrown, that seems to have to do with your data and use of the JMF.
Generally, it's bad to use System.out.println() on exceptions because then you lose the stack trace, which is often the most important information for debugging. Instead. use exception.printStackTrace();
datasink is never being initialized.
When you try to call
datasink.close();
Its saying that datasink is null.
Make sure that your code is actually getting to and processing line #176
datasink = Manager.createDataSink(outputDS, ml);
By looking at the private void startCapture() method I guess the processor variable is NULL as this is the only stuff that is not in a try-catch block.
Remove this :
Processor processor = null;
DataSink datasink = null;
and replace with this :
Processor processor;
DataSink datasink;
This is because of createRealizedProcessor is not able to work on VedioCapture device.
Issue is with Microsoft WDM Image device.