Im trying to run some WMI queries using JACOB, and so far i've been successfull in getting the services and processes however i need to query the registry to see if a certain key is there
i've stummbled across this link
but i dont understand how to implement it
in order to query the services i've used the following code
ActiveXComponent wmi = null;
wmi = new ActiveXComponent("WbemScripting.SWbemLocator"); <-- side question what is the WbemScripting...
variantParameters[0] = new Variant("localhost");
variantParameters[1] = new Variant("root\\cimv2"); <-- what is this root?
String query = "Select ExitCode,Name,ProcessId,StartMode,State,Status from Win32_Service where State='Running' and Name='MSDTC'";
Variant vCollection = wmiconnect
.invoke("ExecQuery", new Variant(query));
is there a place with decent documentation for this?
and how to implement queries on the registry?
Thanks
UPDATE
Im trying a new implementation where i try to call the StdRegProv
and i have the following code
int HKEY_LOCAL_MACHINE = 0x80000002;
String strKeyPath = "SYSTEM\\CurrentControlSet\\Services";
String [] sNames = new String [5];
ActiveXComponent wmi = new ActiveXComponent("WbemScripting.SWbemLocator");
// no connection parameters means to connect to the local machine
Variant variantParameters[] = new Variant[4];
variantParameters[0] = new Variant("192.168.1.2");
variantParameters[1] = new Variant("root\\default");
variantParameters[2] = new Variant("admin");
variantParameters[3] = new Variant("pass");
Dispatch services = wmi.invoke("ConnectServer", variantParameters).toDispatch();
Dispatch oReg = Dispatch.call(services, "Get", "StdRegProv").toDispatch();
Variant ret = Dispatch.call(oReg, "EnumKey", HKEY_LOCAL_MACHINE, strKeyPath, sNames);
System.out.println("EnumKey: HKEY_LOCAL_MACHINE\\"+strKeyPath+"="+ret);
I was hoping to get the sNames array filled with data but its just nulls
I was unable to do it with Jacob but succeeded using j-interop library
here is the code that cost me so much suffering
IJIAuthInfo authInfo = new JIDefaultAuthInfoImpl("remoteComputerIpAddress", "wmiUserName", "wmiUserPassword");
IJIWinReg registry = null;
try {
registry = JIWinRegFactory.getSingleTon().getWinreg(authInfo, "remoteComputerIpAddress", true);
JIPolicyHandle policyHandle = registry.winreg_OpenHKLM();
JIPolicyHandle policyHandle2 = registry.winreg_OpenKey(policyHandle, "SOFTWARE\\wisemon",
IJIWinReg.KEY_ALL_ACCESS);
// JIPolicyHandle policyHandle3 =
// registry.winreg_OpenKey(policyHandle2,"wisemon",IJIWinReg.KEY_ALL_ACCESS);
System.out.println("Printing first 1000 entries under HKEY_LOCAL_MACHINE\\BCD00000000...");
for (int i = 0; i < 1; i++) {
// String[] values = registry.winreg_EnumKey(policyHandle3,i);
// Object[] values = registry.winreg_EnumValue(policyHandle3,i);
Object[] values = registry.winreg_QueryValue(policyHandle2, "name", 100);
Object[] values2 = registry.winreg_QueryValue(policyHandle2, "date", 100);
System.out.println(new String((byte[]) values[1]));
System.out.println(new String((byte[]) values2[1]));
}
} catch (UnknownHostException | JIException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
System.out.println("Closing registry connection");
registry.closeConnection();
}
Related
I have the XML document of the various types of OPC UA and some custom object types added to it.. for eg((1) StudentType with properties of Age, Birthplace (2) TeacherType with properties of Name, Expertise))
Also, I have another text input which says (XX -- FolderType, AA -- StudentType, BB --TeacherType) Inshort it mentions the instance name and the type of the instance.
This complete thing can be built with UAModeller tool ofcourse, however we plan to write a java program which does this for us automatically when inputs are provided.
To start off, I have taken the types.xml file, and have parsed it. I have created a list of UAObjectTypes, UAVariableTypes, StudentTypes,TeacherTypes etc.
I have made myself a list which maps the inputlist of instances, to their ObjectTypes.
But I am not able to establish the references as expected.
For eg:
Every node in OPC UA is connected to the other via references. For eg: Class is "OrganisedBy" Objects. Class "organises" Students and Teachers. Students "organises" Rakshan and so on.
I am struggling to establish a dynamic production of this address Space via code.
I have the sample address sace produced by the tool. But the java program does not produce the same.
File xmlFile = new File("studteachobjmodel.xml"); //this is the types.xml
JAXBContext jaxbContext;
jaxbContext = JAXBContext.newInstance(UANodeSet.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
UANodeSet xmlentries = (UANodeSet) jaxbUnmarshaller.unmarshal(xmlFile);
entries.add(xmlentries);
//This has to be well known in prior
UANodeSet newUANodeSetObject = new UANodeSet();
List<UAObjectType> objectTypeList = xmlentries.getUAObjectType();
HashMap<String, UAObjectType> mapWithExtractedObjectTypes = new HashMap<String, UAObjectType>();
for(String name: newUniqueList) {
for(UAObjectType o : objectTypeList) {
if(o.getDisplayName().equals(name))
mapWithExtractedObjectTypes.put(o.getDisplayName(), o); //mapping types with their objectTypes
}
}
System.out.println("----------MAPPING DONE---------------------");
List<UAObject> objectList = xmlentries.getUAObject();
List<UAObject> newObjectList = new ArrayList<UAObject>();
UAObject uaObject = null;
List<String> newNameSpaceUris = new ArrayList<String>();
newNameSpaceUris.add("http://yourorganisation.org/trial1/");
newUANodeSetObject.setNamespaceUris(newNameSpaceUris);
List<UAVariable> variableList = new ArrayList<UAVariable>();
for(Map.Entry mapElement:inputMap.entrySet()) {
String key = (String) mapElement.getKey();
String type = inputMap.get(key);
String value = mapWithExtractedObjectTypes.get(type).getNodeId();
UAObjectType tempType =mapWithExtractedObjectTypes.get(type);
// String value = opcuaInternalMap.get(type);
for(UAObjectType o : objectTypeList) {
if (o.getNodeId().equals(value))
{
// System.out.println(o.getReferences());
uaObject = new UAObject();
List<Reference> referencesForObject = new ArrayList<Reference>();
uaObject.setNodeId("ns=1;s="+key);//String.valueOf(min+random.nextInt(upperBound)));
uaObject.setBrowsename("1:"+key);
uaObject.setDisplayName(key);
List<Reference>tempRef=tempType.getReferences();
Reference ref_01= new Reference();
ref_01.setReferenceType("HasTypeDefinition");
ref_01.setReference(value);
//
////////////////////////NEED GUIDANCE HERE//////////////////////////////////
// Reference ref_02= new Reference();
// ref_02.setReferenceType("Organizes");
// ref_02.setReference("i=85");
// referencesForObject.add(ref_01);
// referencesForObject.add(ref_02);
tempRef.add(ref_01);
uaObject.setReferences(tempRef);
break;
}
}
if(uaObject!=null) {
newObjectList.add(uaObject);
}
newUANodeSetObject.setUAObject(newObjectList);
}
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(newUANodeSetObject, new File("Instances.xml"));
}catch (JAXBException e) {
e.printStackTrace();
} catch (FactoryConfigurationError e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Please provide me some guidance. totally clueless as of now.
I've been trying to figure out how to use WordNet synonyms with a search function I'm developing which uses Hibernate Search 5.6.1. At first, I thought about using Hibernate Search annotations:
#TokenFilterDef(factory = SynonymFilterFactory.class, params = {#Parameter(name = "ignoreCase", value = "true"),
#Parameter(name = "expand", value = "true"),#Parameter(name = "synonyms", value = "synonymsfile") })
However, this requires an actual file populated with synonyms. From WordNet I was only able to get ".pl" files. So I tried manually making a SynonymAnalyzer class which would read from the ".pl" file:
public class SynonymAnalyzer extends Analyzer {
#Override
protected TokenStreamComponents createComponents(String fieldName) {
final Tokenizer source = new StandardTokenizer();
TokenStream result = new StandardFilter(source);
result = new LowerCaseFilter(result);
SynonymMap wordnetSynonyms = null;
try {
wordnetSynonyms = loadSynonyms();
} catch (IOException e) {
e.printStackTrace();
}
result = new SynonymFilter(result, wordnetSynonyms, false);
result = new StopFilter(result, StopAnalyzer.ENGLISH_STOP_WORDS_SET);
return new TokenStreamComponents(source, result);
}
private SynonymMap loadSynonyms() throws IOException {
File file = new File("synonyms\\wn_s.pl");
InputStream stream = new FileInputStream(file);
Reader reader = new InputStreamReader(stream);
SynonymMap.Builder parser = null;
parser = new WordnetSynonymParser(true, true, new StandardAnalyzer(CharArraySet.EMPTY_SET));
try {
((WordnetSynonymParser) parser).parse(reader);
} catch (ParseException e) {
e.printStackTrace();
}
return parser.build();
}
}
The problem with this method is that I'm getting java.lang.OutOfMemoryError which I'm assuming is because there's too many synonyms or something? What is the proper way to do this, everywhere I've looked online has suggested using WordNet but I can't seem to find an example with Hibernate Search Annotations. Any help is appreciated, thanks!
The wordnet format is actually supported by SynonymFilterFactory. You're simply missing the "format" parameter in your annotation configuration; by default, the factory uses the Solr format.
Change your annotation to this:
#TokenFilterDef(
factory = SynonymFilterFactory.class,
params = {
#Parameter(name = "ignoreCase", value = "true"),
#Parameter(name = "expand", value = "true"),
#Parameter(name = "synonyms", value = "synonymsfile"),
#Parameter(name = "format", value = "wordnet") // Add this
}
)
Also, make sure that the value of the "synonyms" parameter is the path of a file in your classpath (e.g. "com/acme/synonyms.pl", or just "synonyms.pl" if the file is at the root of your "resources" directory).
In general when you have an issue with the parameters of a Lucene filter/tokenizer factory, your best bet is having a look at the source code of that factory, or having a look at this page.
I am trying to take a very long file of strings and convert it to an XML according to a schema I was given. I used jaxB to create classes from that schema. Since the file is very large I created a thread pool to improve the performance but since then it only processes one line of the file and marshalls it to the XML file, per thread.
Below is my home class where I read from the file. Each line is a record of a transaction, for every new user encountered a list is made to store all of that users transactions and each list is put into a HashMap. I made it a ConcurrentHashMap because multiple threads will work on the map simultaneously, is this the correct thing to do?
After the lists are created a thread is made for each user. Each thread runs the method ProcessCommands below and receives from home the list of transactions for its user.
public class home{
public static File XMLFile = new File("LogFile.xml");
Map<String,List<String>> UserMap= new ConcurrentHashMap<String,List<String>>();
String[] UserNames = new String[5000];
int numberOfUsers = 0;
try{
BufferedReader reader = new BufferedReader(new FileReader("test.txt"));
String line;
while ((line = reader.readLine()) != null)
{
parsed = line.split(",|\\s+");
if(!parsed[2].equals("./testLOG")){
if(Utilities.checkUserExists(parsed[2], UserNames) == false){ //User does not already exist
System.out.println("New User: " + parsed[2]);
UserMap.put(parsed[2],new ArrayList<String>()); //Create list of transactions for new user
UserMap.get(parsed[2]).add(line); //Add First Item to new list
UserNames[numberOfUsers] = parsed[2]; //Add new user
numberOfUsers++;
}
else{ //User Already Existed
UserMap.get(parsed[2]).add(line);
}
}
}
reader.close();
} catch (IOException x) {
System.err.println(x);
}
//get start time
long startTime = new Date().getTime();
tCount = numberOfUsers;
ExecutorService threadPool = Executors.newFixedThreadPool(tCount);
for(int i = 0; i < numberOfUsers; i++){
System.out.println("Starting Thread " + i + " for user " + UserNames[i]);
Runnable worker = new ProcessCommands(UserMap.get(UserNames[i]),UserNames[i], XMLfile);
threadPool.execute(worker);
}
threadPool.shutdown();
while(!threadPool.isTerminated()){
}
System.out.println("Finished all threads");
}
Here is the ProcessCommands class. The thread receives the list for its user and creates a marshaller. From what I unserstand marshalling is not thread safe so it is best to create one for each thread, is this the best way to do that?
When I create the marshallers I know that each from (from each thread) will want to access the created file causing conflicts, I used synchronized, is that correct?
As the thread iterates through it's list, each line calls for a certain case. There are a lot so I just made pseudo-cases for clarity. Each case calls the function below.
public class ProcessCommands implements Runnable{
private static final boolean DEBUG = false;
private List<String> list = null;
private String threadName;
private File XMLfile = null;
public Thread myThread;
public ProcessCommands(List<String> list, String threadName, File XMLfile){
this.list = list;
this.threadName = threadName;
this.XMLfile = XMLfile;
}
public void run(){
Date start = null;
int transactionNumber = 0;
String[] parsed = new String[8];
String[] quoteParsed = null;
String[] universalFormatCommand = new String[9];
String userCommand = null;
Connection connection = null;
Statement stmt = null;
Map<String, UserObject> usersMap = null;
Map<String, Stack<BLO>> buyMap = null;
Map<String, Stack<SLO>> sellMap = null;
Map<String, QLO> stockCodeMap = null;
Map<String, BTO> buyTriggerMap = null;
Map<String, STO> sellTriggerMap = null;
Map<String, USO> usersStocksMap = null;
String SQL = null;
int amountToAdd = 0;
int tempDollars = 0;
UserObject tempUO = null;
BLO tempBLO = null;
SLO tempSLO = null;
Stack<BLO> tempStBLO = null;
Stack<SLO> tempStSLO = null;
BTO tempBTO = null;
STO tempSTO = null;
USO tempUSO = null;
QLO tempQLO = null;
String stockCode = null;
String quoteResponse = null;
int usersDollars = 0;
int dollarAmountToBuy = 0;
int dollarAmountToSell = 0;
int numberOfSharesToBuy = 0;
int numberOfSharesToSell = 0;
int quoteStockInDollars = 0;
int shares = 0;
Iterator<String> itr = null;
int transactionCount = list.size();
System.out.println("Starting "+threadName+" - listSize = "+transactionCount);
//UO dollars, reserved
usersMap = new HashMap<String, UserObject>(3); //userName -> UO
//USO shares
usersStocksMap = new HashMap<String, USO>(); //userName+stockCode -> shares
//BLO code, timestamp, dollarAmountToBuy, stockPriceInDollars
buyMap = new HashMap<String, Stack<BLO>>(); //userName -> Stack<BLO>
//SLO code, timestamp, dollarAmountToSell, stockPriceInDollars
sellMap = new HashMap<String, Stack<SLO>>(); //userName -> Stack<SLO>
//BTO code, timestamp, dollarAmountToBuy, stockPriceInDollars
buyTriggerMap = new ConcurrentHashMap<String, BTO>(); //userName+stockCode -> BTO
//STO code, timestamp, dollarAmountToBuy, stockPriceInDollars
sellTriggerMap = new HashMap<String, STO>(); //userName+stockCode -> STO
//QLO timestamp, stockPriceInDollars
stockCodeMap = new HashMap<String, QLO>(); //stockCode -> QLO
//create user object and initialize stacks
usersMap.put(threadName, new UserObject(0, 0));
buyMap.put(threadName, new Stack<BLO>());
sellMap.put(threadName, new Stack<SLO>());
try {
//Marshaller marshaller = getMarshaller();
synchronized (this){
Marshaller marshaller = init.jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
marshaller.marshal(LogServer.Root,XMLfile);
marshaller.marshal(LogServer.Root,System.out);
}
} catch (JAXBException M) {
M.printStackTrace();
}
Date timing = new Date();
//universalFormatCommand = new String[8];
parsed = new String[8];
//iterate through workload file
itr = this.list.iterator();
while(itr.hasNext()){
userCommand = (String) itr.next();
itr.remove();
parsed = userCommand.split(",|\\s+");
transactionNumber = Integer.parseInt(parsed[0].replaceAll("\\[", "").replaceAll("\\]", ""));
universalFormatCommand = Utilities.FormatCommand(parsed, parsed[0]);
if(transactionNumber % 100 == 0){
System.out.println(this.threadName + " - " +transactionNumber+ " - "+(new Date().getTime() - timing.getTime())/1000);
}
/*System.out.print("UserCommand " +transactionNumber + ": ");
for(int i = 0;i<8;i++)System.out.print(universalFormatCommand[i]+ " ");
System.out.print("\n");*/
//switch for user command
switch (parsed[1].toLowerCase()) {
case "One"
*Do Stuff"
LogServer.create_Log(universalFormatCommand, transactionNumber, CommandType.ADD);
break;
case "Two"
*Do Stuff"
LogServer.create_Log(universalFormatCommand, transactionNumber, CommandType.ADD);
break;
}
}
}
The function create_Log has multiple cases so as before, for clarity I just left one. The case "QUOTE" only calls one object creation function but other other cases can create multiple objects. The type 'log' is a complex XML type that defines all the other object types so in each call to create_Log I create a log type called Root. The class 'log' generated by JaxB included a function to create a list of objects. The statement:
Root.getUserCommandOrQuoteServerOrAccountTransaction().add(quote_QuoteType);
takes the root element I created, creates a list and adds the newly created object 'quote_QuoteType' to that list. Before I added threading this method successfully created a list of as many objects as I wanted then marshalled them. So I'm pretty positive the bit in class 'LogServer' is not the issue. It is something to do with the marshalling and syncronization in the ProcessCommands class above.
public class LogServer{
public static log Root = new log();
public static QuoteServerType Log_Quote(String[] input, int TransactionNumber){
ObjectFactory factory = new ObjectFactory();
QuoteServerType quoteCall = factory.createQuoteServerType();
**Populate the QuoteServerType object called quoteCall**
return quoteCall;
}
public static void create_Log(String[] input, int TransactionNumber, CommandType Command){
System.out.print("TRANSACTION "+TransactionNumber + " is " + Command + ": ");
for(int i = 0; i<input.length;i++) System.out.print(input[i] + " ");
System.out.print("\n");
switch(input[1]){
case "QUOTE":
System.out.print("QUOTE CASE");
QuoteServerType quote_QuoteType = Log_Quote(input,TransactionNumber);
Root.getUserCommandOrQuoteServerOrAccountTransaction().add(quote_QuoteType);
break;
}
}
So you wrote a lot of code, but have you try if it is actually working? After quick look I doubt it. You should test your code logic part by part not going all the way till the end. It seems you are just staring with Java. I would recommend practice first on simple one threaded applications. Sorry if I sound harsh, but I will try to be constructive as well:
Per convention, the classes names are starts with capital letter, variables by small, you do it other way.
You should make a method in you home (Home) class not a put all your code in the static block.
You are reading the whole file to the memory, you do not process it line by line. After the Home is initialized literary whole content of file will be under UserMap variable. If the file is really large you will run out of the heap memory. If you assume large file than you cannot do it and you have to redisign your app to store somewhere partial results. If your file is smaller than memmory you could keep it like that (but you said it is large).
No need for UserNames, the UserMap.containsKey will do the job
Your thread pools size should be in the range of your cores not number of users as you will get thread trashing (if you have blocking operation in your code make tCount = 2*processors if not keep it as number of processors). Once one ProcessCommand finish, the executor will start another one till you finish all and you will be efficiently using all your processor cores.
DO NOT while(!threadPool.isTerminated()), this line will completely consume one processor as it will be constantly checking, call awaitTermination instead
Your ProcessCommand, has view map variables which will only had one entry cause as you said, each will process data from one user.
The synchronized(this) is Process will not work, as each thread will synchronized on different object (different isntance of process).
I believe creating marshaller is thread safe (check it) so no need to synchronization at all
You save your log (whatever it is) before you did actual processing in of the transactions lists
The marshalling will override content of the file with current state of LogServer.Root. If it is shared bettween your proccsCommand (seems so) what is the point in saving it in each thread. Do it once you are finished.
You dont need itr.remove();
The log class (for the ROOT variable !!!) needs to be thread-safe as all the threads will call the operations on it (so the list inside the log class must be concurrent list etc).
And so on.....
I would recommend, to
Start with simple one thread version that actually works.
Deal with processing line by line, (store reasults for each users in differnt file, you can have cache with transactions for recently used users so not to keep writing all the time to the disk (see guava cache)
Process multithreaded each user transaction to your user log objects (again if it is a lot you have to save them to the disk not keep all in memmory).
Write code that combines logs from diiffernt users to create one (again you may want to do it mutithreaded), though it will be mostly IO operations so not much gain and more tricky to do.
Good luck
override cont
Good Morning,
I’am using Jacob 1.17 o read all my Outlook Contact Pictures and save them to an File. The Procedure works pretty fine for the first 199 Contatcs. After that the Dispatch.call fails and terminates with the following Exception:
Exception in thread "main" com.jacob.com.ComFailException: Invoke of: SaveAsFile
Source: Microsoft Outlook
Description: Cannot save the attachment. Cannot create file: ContactPicture.jpg.
Right-click the folder you want to create the file in, and then click Properties on
the shortcut menu to check your permissions for the folder.
at com.jacob.com.Dispatch.invokev(Native Method)
at com.jacob.com.Dispatch.invokev(Dispatch.java:625)
at com.jacob.com.Dispatch.callN(Dispatch.java:453)
at com.jacob.com.Dispatch.call(Dispatch.java:541)
at outlookStuff.ManageContactsOutlook.tmpTest(ManageContactsOutlook.java:217)
at mainPackage.Main.main(Main.java:32)
I’m really not sure way. I tested a different set of Contacts – same Error. Set all Objects to null to make shore that the Garbage Collector is involved but it doesn’t help.
The piece of Code which makes the trouble:
public void tmpTest(int intOutlookFolder, String strWorkingDir) {
Dispatch dipNamespace = this.axc.getProperty("Session").toDispatch();
Dispatch dipContactsFolder = Dispatch.call(dipNamespace, "GetDefaultFolder", (Object) new Integer(intOutlookFolder)).toDispatch();
Dispatch dipContactItems = Dispatch.get(dipContactsFolder, "items").toDispatch();
#SuppressWarnings("deprecation")
int count = Dispatch.call(dipContactItems, "Count").toInt();
for (int i=1; i<=count; i++) {
Dispatch dipContact;
dipContact = Dispatch.call(dipContactItems, "Item", new Integer(i)).toDispatch();
String strEntryID = Dispatch.get(dipContact, "EntryID").toString().trim();
//For Testing
Status.printStatusToConsole("Outlook Contact "+strEntryID+" loaded");
byte[] byteContactPicture = null;
String strPathToTmpPicture = null;
Dispatch dipAttachments = Dispatch.get(dipContact, "Attachments").toDispatch();
#SuppressWarnings("deprecation")
int countAttachements = Dispatch.call((Dispatch) dipAttachments, "Count").toInt();
for (int j=1; j<=countAttachements; j++) {
Dispatch currentAttachement;
currentAttachement = Dispatch.call(dipAttachments, "Item", new Integer(j)).toDispatch();
if (Dispatch.get(currentAttachement, "FileName").toString().equals("ContactPicture.jpg")) {
strPathToTmpPicture = strWorkingDir+strEntryID+".jpg";
//The Crashing Part
Dispatch.call(currentAttachement, "SaveAsFile", strPathToTmpPicture);
File tmpFile = new File(strPathToTmpPicture);
if (tmpFile.exists()) {
try {
byteContactPicture = org.apache.commons.io.FileUtils.readFileToByteArray(tmpFile);
} catch (IOException e) {
e.printStackTrace();
}
}
currentAttachement = null;
tmpFile = null;
}
currentAttachement = null;
}
dipAttachments = null;
}
dipContactItems = null;
dipContactsFolder = null;
dipNamespace = null;
}
May someone has an idea?
Thanks
Aviation
When I try to create a new OpportunityLineItemSchedule I'm running into following error..
Error code: INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY
Error message: insufficient access rights on cross-reference id
Attached is the code snippet. Any help will be extremely useful.
SObject[] rs = new SObject[1];
MessageElement[] specificRS = new MessageElement[6];
specificRS[0] = new MessageElement(new QName("OpportunityLineItemId"),"00k7000000DFLqfAAH");
specificRS[1] = new MessageElement(new QName("Description"),"Rev Schedule Descr");
specificRS[2] = new MessageElement(new QName("Type"),"Quantity");
specificRS[3] = new MessageElement(new QName("Quantity"),(double)2);
specificRS[4] = new MessageElement(new QName("Revenue"),(double)400000.00);
specificRS[5] = new MessageElement(new QName("ScheduleDate"),"2010-10-30");
rs[0] = new SObject();
rs[0].setType("OpportunityLineItemSchedule");
rs[0].set_any(specificRS);
SaveResult[] sr = null;
try {
sr = binding.create(rs);
} catch (Exception ex) {
System.out.println("An unexpected error has occurred." + ex.getMessage());
ex.printStackTrace();
return;
}
Following works..
MessageElement[] specificRS2 = new MessageElement[5];
specificRS2[0] = new MessageElement(new QName("OpportunityLineItemId"),"00k7000000DFcOG");
// PricebookEntryId can be found by joining PricebookEntry and Pricebook2 tables (on Product2Id and
specificRS2[1] = new MessageElement(new QName("Description"),"Rev Schedule Descr2");
specificRS2[2] = new MessageElement(new QName("ScheduleDate"),"2010-10-31");
//specificRS[3] = new MessageElement(new QName("Quantity"),(double)2);
specificRS2[3] = new MessageElement(new QName("Revenue"),(double)10.00);
//specificRS[4] = new MessageElement(new QName("Type"),"Quantity"); // and/or "Revenue"
specificRS2[4] = new MessageElement(new QName("Type"),"Revenue"); // and/or "Quantity"
rs[1] = new SObject();
rs[1].setType("OpportunityLineItemSchedule");
rs[1].set_any(specificRS2);
SaveResult[] sr = null;
try {
sr = binding.create(rs);
} catch (Exception ex) {
System.out.println("An unexpected error has occurred." + ex.getMessage());
ex.printStackTrace();
return;
}
This is usually an error when code is trying to use an ID for an object that doesn't exist, or that the user doesn't have access to. I take it the only difference between the 2 snippets is the OpportunityLineItem ID? Check that the user running the code can access the item with that ID.
Have a look at the Allowed Type Field Values and Allowed Quantity and Revenue Field Values documentation for OpportunityLineItemSchedule.
The allowed Type values for an OpportunityLineItemSchedule depend on the product-level schedule preferences and whether the line item has any existing schedules
You may need to check if there are existing OpportunityLineItemSchedule records.
The allowable Quantity and Revenue field values depend on the value of the Type field
You only set the Quantity or Revenue field, not both.