Jacob Fatal Error - java

I am trying to build a Java Drag and Drop that works with Outlook emails. I've been using Jacob because of an inability to transfer data from Outlook to Java using standard AWT Event stuff. That said, all of the solutions I've pulled from here or other sites have been causing a fatal crash in Java. Here's the code:
import java.awt.dnd.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.awt.datatransfer.*;
import java.io.*;
import java.util.List;
import sun.awt.datatransfer.*;
import com.jacob.com.*;
import com.jacob.activeX.*;
public class D2 extends JFrame
{
private static final String DIR = "FILES";
private static void saveSelectedOutlookMails(String directory) {
Dispatch xl = new Dispatch("Outlook.Application");
//Dispatch selection = Dispatch.get(xl, "Selection").toDispatch();
System.out.println(xl);
System.out.println(xl==null);
//PROGRAM CRASHES AFTER THIS LINE
Dispatch explorer = Dispatch.get(xl,"ActiveExplorer").toDispatch();
System.out.println("explorer");
Object selection = Dispatch.get(explorer, "Selection").toDispatch();
Variant count = Dispatch.get(selection, "Count");
for (int mailIndex = 1; mailIndex <= count.toInt(); mailIndex++ ) {
Object mailItem = Dispatch.call(selection, "Item", new Variant(mailIndex)).toDispatch();
Variant senderName = Dispatch.get(mailItem, "SenderName");
Variant subject = Dispatch.get(mailItem, "Subject");
Variant body = Dispatch.get(mailItem, "Body");
String emailFileName = subject.toString() +".txt";
String fullPath = directory + "/" + emailFileName;
try {
File email = new File(fullPath);
PrintWriter writer = new PrintWriter( new FileWriter(email) );
writer.println("From: "+ senderName );
writer.println("Subject: "+ subject);
writer.println("");
writer.print( body );
writer.close();
}
catch (IOException e) {
System.out.println(e.getMessage());
//logger.error("IOException writing e-mail with subject: '"+ subject +"'", e);
continue;
}
Object attachments = Dispatch.get(mailItem, "Attachments").toDispatch();
Variant attachmentCount = Dispatch.get(attachments, "Count");
if ( attachmentCount.toInt() > 0 ) {
for( int attachmentIndex = 1; attachmentIndex<=attachmentCount.toInt(); attachmentIndex++ ) {
Object attachment = Dispatch.call(attachments, "Item", new Variant(attachmentIndex)).toDispatch();
Variant fileNameVariant = Dispatch.get(attachment, "FileName");
String fileName = fileNameVariant.toString();
Variant saveResult = Dispatch.call(attachment, "SaveAsFile", directory, "/", fileName);
}
}
}
}
public D2() throws Exception
{
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setBounds(0,0,300,300);
this.setVisible(true);
DropTarget dropTarget=new DropTarget();
dropTarget.setComponent(this);
dropTarget.addDropTargetListener(new DropTargetAdapter()
{
public void drop(DropTargetDropEvent dtde){
saveSelectedOutlookMails(DIR);
}
});
}
public static void main(String[] args)
{
try{
new D2();
}catch(Exception e){
e.printStackTrace();
}
}
}

Ok, firstly, you are creating Outlook.Application in a way I've never seen before - I've only ever seen the Active X Component way:
e.g.
ActiveXComponent xl = new ActiveXComponent("Outlook.Application");
Dispatch explorer = Dispatch.get(xl,"ActiveExplorer").toDispatch();
Dispatch selection = Dispatch.get(explorer, "Selection").toDispatch();
Variant count = Dispatch.get(selection, "Count");
// loop over selected mail items.
for (int mailIndex = 1; mailIndex <= count.getInt(); mailIndex++ ) {
Dispatch mailItem = Dispatch.call(selection, "Item", new Variant(mailIndex)).toDispatch();
Variant subject = Dispatch.get(mailItem, "Subject");
// .... and so on
}
Secondly, your code is not saving the mail, its pulling out all the fields and attachments and trying to recreate the mail, which seems inaccurate at best and will only be an approximation of what the message was.
Why don't you just use the COM objects to SaveAs the whole .msg file to disk? Then if you need to access it again you can use something like JDIC to launch Outlook and pop up the message in its original glory, including all attachments?

My guess is that you are trying to get PROPERTY with name "ActiveExplorer", but it is a method! Here is documentation of that particuliar method https://msdn.microsoft.com/en-us/library/office/ff870017.aspx . Try to use .call() Jacob method to invoke METHODS on MS objects.

Related

sending mailchimp campaign with maleorang v3.0 java api

I have gotten so far that I can create a new campaign in my campaign list in mailchimp using a java class, however, I am not getting there to send it, see code, does anyone have suggestions?
it executes the creation of the campaign (and i see it in mailchimp), and I receive back the campaignInfo object, but from the point to send this campaign, I cant figure it out
package mailingapp2;
import com.ecwid.maleorang.MailchimpClient;
import com.ecwid.maleorang.method.v3_0.campaigns.CampaignActionMethod;
import com.ecwid.maleorang.method.v3_0.campaigns.CampaignInfo;
import com.ecwid.maleorang.method.v3_0.campaigns.CampaignInfo.SettingsInfo;
import static com.ecwid.maleorang.method.v3_0.campaigns.CampaignInfo.Type.PLAINTEXT;
import com.ecwid.maleorang.method.v3_0.campaigns.EditCampaignMethod;
public class SendMailchimpCampaign {
public void SendCampaign() throws Exception {
String apiKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
String listId = "d069f8c902";
String Email ="test#test.be";
String firstName = "test";
String lastName = "test";
MailchimpClient client = new MailchimpClient(apiKey);
try{
EditCampaignMethod.Create method = new EditCampaignMethod.Create();
method.type = PLAINTEXT;
method.settings = new SettingsInfo();
method.settings.mapping.put("title", "test2");
method.settings.mapping.put("subject_line", "test");
method.settings.mapping.put("from_name", "test");
method.settings.mapping.put("reply_to", "info#test.be");
CampaignInfo campaign = client.execute(method); //until here it works, //it executes, and I receive back the campaignInfo object, but from here I can't //figure it out how to move on to send this campaign.
CampaignActionMethod.Send send = new CampaignActionMethod.Send(listId);
System.out.println("info" + campaign);
}catch (Exception e) {
System.err.println("Caught IOException: " + e.getMessage());
}
}
}
It seems you should add
client.execute(send);
right after
CampaignActionMethod.Send send = new CampaignActionMethod.Send(listId);

How to retrieve a list of included client libs from a component in CQ?

Is it possible to determine, what client libs have been loaded prior to a component?
We are running multiple site backed by different Javascript frameworks. In order to run a single component across the board, it's not sufficient to just use
<cq:includeClientLib categories="blah"/>
We need to identify the respective framework (i.e. AngularJS, Vanilla, jQuery, blah) in order to facilitate the integration.
We are looking for a decent server side solution.
I haven't actually done this, but it would presumably be possible if you are buffering your output to clone the JspWriter buffer or examine it to see what it already contains. That sounds ugly to me, though. But this is decompiled code for how the cq:includeClientLib tag adds libraries to the output, which may show you how you can read back what was previously written:
package com.adobe.granite.ui.tags;
import com.day.cq.widget.HtmlLibraryManager;
import java.io.IOException;
import javax.servlet.ServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.TagSupport;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.scripting.SlingBindings;
import org.apache.sling.scripting.jsp.util.TagUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class IncludeClientLibraryTag extends TagSupport {
private static final long serialVersionUID = -3068291967085012331L;
private static final Logger log = LoggerFactory.getLogger(IncludeClientLibraryTag.class);
private String categories;
private String js;
private String css;
private String theme;
private Boolean themed;
public IncludeClientLibraryTag() {
}
public void setPageContext(PageContext pageContext) {
super.setPageContext(pageContext);
this.categories = null;
this.js = null;
this.css = null;
this.theme = null;
this.themed = null;
}
public void setCategories(String categories) {
this.categories = categories;
}
public void setJs(String js) {
this.js = js;
}
public void setCss(String css) {
this.css = css;
}
public void setTheme(String theme) {
this.theme = theme;
}
public void setThemed(boolean themed) {
this.themed = Boolean.valueOf(themed);
}
public int doEndTag() throws JspException {
SlingHttpServletRequest request = TagUtil.getRequest(this.pageContext);
HtmlLibraryManager libManager = this.getHtmlLibraryManager(request);
if(libManager == null) {
log.warn("<ui:includeClientLib>: Could not retrieve HtmlLibraryManager service, skipping inclusion.");
return 6;
} else {
JspWriter out = this.pageContext.getOut();
try {
if(this.categories != null) {
libManager.writeIncludes(request, out, toArray(this.categories));
} else if(this.theme != null) {
libManager.writeThemeInclude(request, out, toArray(this.theme));
} else if(this.js != null) {
if(this.themed != null) {
libManager.writeJsInclude(request, out, this.themed.booleanValue(), toArray(this.js));
} else {
libManager.writeJsInclude(request, out, toArray(this.js));
}
} else if(this.css != null) {
if(this.themed != null) {
libManager.writeCssInclude(request, out, this.themed.booleanValue(), toArray(this.css));
} else {
libManager.writeCssInclude(request, out, toArray(this.css));
}
}
return 6;
} catch (IOException var6) {
String libs = this.categories != null?"categories: " + this.categories:(this.theme != null?"theme: " + this.theme:(this.js != null?"js: " + this.js:(this.css != null?"css: " + this.css:"")));
throw new JspException("Could not include client library: " + libs, var6);
}
}
}
private HtmlLibraryManager getHtmlLibraryManager(ServletRequest request) {
SlingBindings bindings = (SlingBindings)request.getAttribute(SlingBindings.class.getName());
return (HtmlLibraryManager)bindings.getSling().getService(HtmlLibraryManager.class);
}
private static String[] toArray(String commaSeparatedList) {
if(commaSeparatedList == null) {
return new String[0];
} else {
String[] split = commaSeparatedList.split(",");
for(int i = 0; i < split.length; ++i) {
split[i] = split[i].trim();
}
return split;
}
}
}
I think the best solution may be to use the client library dependencies or embed attributes in your library, though, or let the client-side JavaScript test if a library is present (ex. test if the jQuery object is undefined) and then take appropriate action. In other words, let the client side determine the final rendering based on what libraries exist on in the client. It sounds like this may not be possible for your situation, though.
dependencies: This is a list of other client library categories on
which this library folder depends. For example, given two
cq:ClientLibraryFolder nodes F and G, if a file in F requires another
file in G in order to function properly, then at least one of the
categories of G should be among the dependencies of F.
embed: Used to > embed code from other libraries. If node F embeds nodes G and H, the
resulting HTML will be a concetration of content from nodes G and H.

sessionManager cannot be resolved issueaction handler of java swings in export operations using documentum

I am facing an issue in my action handler code to handle the export operation in documentum ** code 2**. Here code 1 is the code for Jbuttons and Jtext and code 3 is the code for the export operations. Here in the section that is causing problem:-
jLabel_messages.setText(te.exportExample(sessionManager,repository,docId,targetLocalDirectory)); ,I am getting an error message for the first parameter sessionManger that says: "sessionManager cannot be resolved". I tried to instantiate the sessionManager as well in the code like IDFsessionManager sessionManager = null; but it didn't solve the issue and the error still occurred.
Can anyone help me or suggest me the changes I need to do for my below code to rectify this issue?
Code1: Button of export invoking the actionevent
jTextField_localDirectory.setBounds(new Rectangle(470, 49, 85, 20));
jLabel_exportFolder.setText("Export Documents: ");
jLabel_exportFolder.setBounds(new Rectangle(365, 55, 85, 15));
jLabel_exportFolder.setHorizontalAlignment(SwingConstants.LEFT);
jButton_export.setText("Export Files");
jButton_export.setBounds(new Rectangle(560, 45, 125, 20));
jButton_export.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
jButton_export_actionPerformed(e);
}
});
Code2: Action Handler code for the export operation:
private void jButton_export_actionPerformed(ActionEvent e)
{
String repository = jTextField_repositoryName.getText();
String docId =m_fileIDs.elementAt(list_id.getSelectedIndex()).toString();
String targetLocalDirectory = jTextField_localDirectory.getText();
TutorialExport te = new TutorialExport(); jLabel_messages.setText(te.exportExample(sessionManager,repository,docId,targetLocalDirectory));
}
Code 3: EXPORT CODE:
import com.documentum.com.DfClientX;
import com.documentum.com.IDfClientX;
import com.documentum.fc.client.IDfDocument;
import com.documentum.fc.client.IDfFormat;
import com.documentum.fc.client.IDfSession;
import com.documentum.fc.client.IDfSessionManager;
import com.documentum.fc.client.IDfSysObject;
import com.documentum.fc.common.DfId;
import com.documentum.fc.common.IDfId;
import com.documentum.operations.IDfExportNode;
import com.documentum.operations.IDfExportOperation;
public class TutorialExport
{
public TutorialExport()
{}
public String exportExample(
IDfSessionManager sessionManager,
String repository,
String docId,
String targetLocalDirectory
)
{
IDfSession mySession = null;
StringBuffer sb = new StringBuffer("");
try
{
mySession = sessionManager.getSession(repository);
IDfId idObj =
mySession.getIdByQualification(
"dm_sysobject where r_object_id='" + docId + "'"
);
IDfSysObject sysObj = (IDfSysObject) mySession.getObject(idObj);
IDfClientX clientx = new DfClientX();
IDfExportOperation eo = clientx.getExportOperation();
IDfDocument doc =(IDfDocument) mySession.getObject(new DfId(docId));
IDfExportNode node = (IDfExportNode) eo.add(doc);
IDfFormat format = doc.getFormat();
if (targetLocalDirectory.lastIndexOf("/") !=
targetLocalDirectory.length() - 1
&&
targetLocalDirectory.lastIndexOf("\\") !=
targetLocalDirectory.length()- 1 )
{
targetLocalDirectory += "/";
}
node.setFilePath(targetLocalDirectory + doc.getObjectName() + "." +
format.getDOSExtension());
if (eo.execute())
{
return "Export operation successful." + "\n" + sb.toString();
}
else
{
return "Export operation failed.";
}
}
catch (Exception ex)
{
ex.printStackTrace();
return "Exception has been thrown: " + ex;
}
finally
{
sessionManager.release(mySession);
}
}
}
You didn't provide much details, and I don't have much experience with Java Swing, but, it seems to me that you are trying to use variable sessionManager before you have instantiated it.
Code for instantiating Documentum session manager in your custom app via DFC is something like:
//instantiating client
IDfClient myClient = DfClient.getLocalClient();
// create login info
IDfLoginInfo myLoginInfo = new DfLoginInfo();
myLoginInfo.setUser("user");
myLoginInfo.setPassword("pwd");
// create session manager
IDfSessionManager mySessionManager = myClient.newSessionManager();
mySessionManager.setIdentity("repositoryName", myLoginInfo);

jAudio Feature Extractor : Null Exception

My project is to create an Android app that can perform feature extraction and classification of audio files. So first, I'm creating a Java application as a test run.
I'm attempting to use jAudio's feature extractor package to extract audio features from an audio file.
As a starter, I want to input a .wav file and run the feature extraction operation upon that file, and then store the results as an .ARFF file.
However, I'm getting the below NullPointer Exception error from a package within the project:
Exception in thread "main" java.lang.NullPointerException
at java.io.DataOutputStream.writeBytes(Unknown Source)
at jAudioFeatureExtractor.jAudioTools.FeatureProcessor.writeValuesARFFHeader(FeatureProcessor.java:853)
at jAudioFeatureExtractor.jAudioTools.FeatureProcessor.<init>(FeatureProcessor.java:258)
at jAudioFeatureExtractor.DataModel.extract(DataModel.java:308)
at Mfccarffwriter.main(Mfccarffwriter.java:70)
Initially I thought it was a file permission issue(i.e, the program was not being allowed to write a file because of lack of permissions), but even after granting every kind of permission to Eclipse 4.2.2(I'm running Windows 7, 64 bit version), I'm still getting the NullException bug.
The package code where the offending exception originates from is given below:
/**
* Write headers for an ARFF file. If saving for overall features, this must
* be postponed until the overall features have been calculated. If this a
* perWindow arff file, then all the feature headers can be extracted now
* and no hacks are needed.
* <p>
* <b>NOTE</b>: This procedure breaks if a feature to be saved has a
* variable number of dimensions
*
* #throws Exception
*/
private void writeValuesARFFHeader() throws Exception {
String sep = System.getProperty("line.separator");
String feature_value_header = "#relation jAudio" + sep;
values_writer.writeBytes(feature_value_header); // exception here
if (save_features_for_each_window && !save_overall_recording_features) {
for (int i = 0; i < feature_extractors.length; ++i) {
if (features_to_save[i]) {
String name = feature_extractors[i].getFeatureDefinition().name;
int dimension = feature_extractors[i]
.getFeatureDefinition().dimensions;
for (int j = 0; j < dimension; ++j) {
values_writer.writeBytes("#ATTRIBUTE \"" + name + j
+ "\" NUMERIC" + sep);
}
}
}
values_writer.writeBytes(sep);
values_writer.writeBytes("#DATA" + sep);
}
}
Here's the main application code:
import java.io.*;
import java.util.Arrays;
import com.sun.xml.internal.bind.v2.runtime.RuntimeUtil.ToStringAdapter;
import jAudioFeatureExtractor.Cancel;
import jAudioFeatureExtractor.DataModel;
import jAudioFeatureExtractor.Updater;
import jAudioFeatureExtractor.Aggregators.AggregatorContainer;
import jAudioFeatureExtractor.AudioFeatures.FeatureExtractor;
import jAudioFeatureExtractor.AudioFeatures.MFCC;
import jAudioFeatureExtractor.DataTypes.RecordingInfo;
import jAudioFeatureExtractor.jAudioTools.*;
public static void main(String[] args) throws Exception {
// Display information about the wav file
File extractedFiletoTest = new File("./microwave1.wav");
String randomID = Integer.toString((int) Math.random());
String file_path = "E:/Weka-3-6/tmp/microwave1.wav";
AudioSamples sampledExampleFile = new AudioSamples(extractedFiletoTest,randomID,false);
RecordingInfo[] samplefileInfo = new RecordingInfo[5];
samplefileInfo[1] = new RecordingInfo(randomID, file_path, sampledExampleFile, true);
double samplingrate= sampledExampleFile.getSamplingRateAsDouble();
int windowsize= 4096;
boolean normalize = false;
OutputStream valsavepath = new FileOutputStream(".\\values");
OutputStream defsavepath = new FileOutputStream(".\\definitions");
boolean[] featurestosaveamongall = new boolean[10];
Arrays.fill(featurestosaveamongall, Boolean.TRUE);
double windowoverlap = 0.0;
DataModel mfccDM = new DataModel("features.xml",null);
mfccDM.extract(windowsize, 0.5, samplingrate, true, true, false, samplefileInfo, 1); /// invokes the writeValuesARFFHeader function.
}
}
You can download the whole project (done so far)here.
This may be a bit late but I had the same issue and I tracked it down to the featureKey and featureValue never being set in the DataModel. There is not a set method for these but they are public field. Here is my code:
package Sound;
import jAudioFeatureExtractor.ACE.DataTypes.Batch;
import jAudioFeatureExtractor.DataModel;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class Analysis {
private static String musicFile = "/home/chris/IdeaProjects/AnotherProj/res/SheMovesInHerOwnWay15s.wav";
private static String featureFile = "/home/chris/IdeaProjects/AnotherProj/res/features.xml";
private static String settingsFile = "/home/chris/IdeaProjects/AnotherProj/res/settings.xml";
private static String FKOuputFile = "/home/chris/IdeaProjects/AnotherProj/res/fk.xml";
private static String FVOuputFile = "/home/chris/IdeaProjects/AnotherProj/res/fv.xml";
public static void main(String[] args){
Batch batch = new Batch(featureFile, null);
try{
batch.setRecordings(new File[]{new File(musicFile)});
batch.getAggregator();
batch.setSettings(settingsFile);
DataModel dm = batch.getDataModel();
OutputStream valsavepath = new FileOutputStream(FVOuputFile);
OutputStream defsavepath = new FileOutputStream(FKOuputFile);
dm.featureKey = defsavepath;
dm.featureValue = valsavepath;
batch.setDataModel(dm);
batch.execute();
}
catch (Exception e){
e.printStackTrace();
}
}
}
I created the settings.xml file using the GUI and just copied the features.xml file from the directory where you saved the jar.
Hope this helps

Bug dereferencing after pig udf

The is actually related to the question How can I add row numbers for rows in PIG or HIVE?
The 3rd answer provided by srini works fine, but I have trouble to access the data after the udf.
The udf provided by srini is following
import java.io.IOException;
import java.util.Iterator;
import org.apache.pig.EvalFunc;
import org.apache.pig.backend.executionengine.ExecException;
import org.apache.pig.data.BagFactory;
import org.apache.pig.data.DataBag;
import org.apache.pig.data.Tuple;
import org.apache.pig.data.TupleFactory;
import org.apache.pig.impl.logicalLayer.schema.Schema;
import org.apache.pig.data.DataType;
public class RowCounter extends EvalFunc<DataBag> {
TupleFactory mTupleFactory = TupleFactory.getInstance();
BagFactory mBagFactory = BagFactory.getInstance();
public DataBag exec(Tuple input) throws IOException {
try {
DataBag output = mBagFactory.newDefaultBag();
DataBag bg = (DataBag)input.get(0);
Iterator it = bg.iterator();
Integer count = new Integer(1);
while(it.hasNext())
{ Tuple t = (Tuple)it.next();
t.append(count);
output.add(t);
count = count + 1;
}
return output;
} catch (ExecException ee) {
// error handling goes here
throw ee;
}
}
public Schema outputSchema(Schema input) {
try{
Schema bagSchema = new Schema();
bagSchema.add(new Schema.FieldSchema("RowCounter", DataType.BAG));
return new Schema(new Schema.FieldSchema(getSchemaName(this.getClass().getName().toLowerCase(), input),
bagSchema, DataType.BAG));
}catch (Exception e){
return null;
}
}
}
I wrote a simple test pig script as following
A = load 'input.txt' using PigStorage(' ') as (name:chararray, age:int);
/*
--A: {name: chararray,age: int}
(amy,56)
(bob,1)
(bob,9)
(amy,34)
(bob,20)
(amy,78)
*/
B = group A by name;
C = foreach B {
orderedGroup = order A by age;
generate myudfs.RowCounter(orderedGroup) as t;
}
/*
--C: {t: {(RowCounter: {})}}
({(amy,34,1),(amy,56,2),(amy,78,3)})
({(bob,1,1),(bob,9,2),(bob,20,3)})
*/
D = foreach C generate FLATTEN(t);
/*
D: {t::RowCounter: {}}
(amy,34,1)
(amy,56,2)
(amy,78,3)
(bob,1,1)
(bob,9,2)
(bob,20,3)
*/
The problem is how to use D in later operation. I tried multiple ways, but always got the following error
ava.lang.ClassCastException: java.lang.String cannot be cast to org.apache.pig.data.DataBag
at org.apache.pig.backend.hadoop.executionengine.physicalLayer.expressionOperators.POProject.processInputBag(POProject.java:575)
at org.apache.pig.backend.hadoop.executionengine.physicalLayer.expressionOperators.POProject.getNext(POProject.java:248)
at org.apache.pig.backend.hadoop.executionengine.physicalLayer.PhysicalOperator.getNext(PhysicalOperator.java:316)
at org.apache.pig.backend.hadoop.executionengine.physicalLayer.relationalOperators.POForEach.processPlan(POForEach.java:332)
at org.apache.pig.backend.hadoop.executionengine.physicalLayer.relationalOperators.POForEach.getNext(POForEach.java:284)
at org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.PigGenericMapReduce$Reduce.runPipeline(PigGenericMapReduce.java:459)
at org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.PigGenericMapReduce$Reduce.processOnePackageOutput(PigGenericMapReduce.java:427)
at org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.PigGenericMapReduce$Reduce.reduce(PigGenericMapReduce.java:407)
at org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.PigGenericMapReduce$Reduce.reduce(PigGenericMapReduce.java:261)
at org.apache.hadoop.mapreduce.Reducer.run(Reducer.java:176)
at org.apache.hadoop.mapred.ReduceTask.runNewReducer(ReduceTask.java:572)
at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:414)
at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:256)
My guess is that because we don't have the schema for the tuple inside the bag. if this is the reason, how should I modify the udf?
ok, I found the solution by adding the outputSchema as following
public Schema outputSchema(Schema input) {
try{
Schema.FieldSchema counter = new Schema.FieldSchema("counter", DataType.INTEGER);
Schema tupleSchema = new Schema(input.getField(0).schema.getField(0).schema.getFields());
tupleSchema.add(counter);
Schema.FieldSchema tupleFs;
tupleFs = new Schema.FieldSchema("with_counter", tupleSchema, DataType.TUPLE);
Schema bagSchema = new Schema(tupleFs);
return new Schema(new Schema.FieldSchema("row_counter",
bagSchema, DataType.BAG));
}catch (Exception e){
return null;
}
}
}
Thanks.

Categories

Resources