问:
Hadoop UI not showing the Job Tab, Job Progress and Job History
I am working with the Hadoop Map-Reduce API and exceuting a simple task to calculate the highest templeratures in year as specified through a large input file of arounf 20MB.

Everything is working fine, viz Mapper tasks are working fine, Reducer tasks are working fine and output file is also generated fine.

But the problem is that, i could not see anything on the Hadoop UI page, neither the Job tab, nor the Job Progress and not even the Job History.

Here is my wordcound java file:

```<code>import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

public class WordCount extends Configured implements Tool{

    /**
     * Main function which calls the run method and passes the args using ToolRunner
     * @param args Two arguments input and output file paths
     * @throws Exception
     */
    public static void main(String[] args) throws Exception{
        int exitCode = ToolRunner.run(new WordCount(), args);
        System.exit(exitCode);
    }

    /**
     * Run method which schedules the Hadoop Job
     * @param args Arguments passed in main function
     */
    public int run(String[] args) throws Exception {
        if (args.length != 2) {
            System.err.printf("Usage: %s needs two arguments <input> <output> files\n",
                    getClass().getSimpleName());
            return -1;
        }

        //Initialize the Hadoop job and set the jar as well as the name of the Job
        Job job = new Job();
        job.setJarByClass(WordCount.class);
        job.setJobName("WordCounter");

        //Add input and output file paths to job based on the arguments passed
        FileInputFormat.addInputPath(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);
        job.setOutputFormatClass(TextOutputFormat.class);

        //Set the MapClass and ReduceClass in the job
        job.setMapperClass(MapClass.class);
        job.setReducerClass(ReduceClass.class);

        //Wait for the job to complete and print if the job was successful or not
        int returnValue = job.waitForCompletion(true) ? 0:1;

        if(job.isSuccessful()) {
            System.out.println("Job was successful");
        } else if(!job.isSuccessful()) {
            System.out.println("Job was not successful");
        }

        return returnValue;
    }
}
</code>```

Here are my hadoop configuration files:

hdfs-site.xml

```<code><?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<configuration>
  <property>
    <name>dfs.replication</name>
    <value>1</value>
  </property>

  <property>
    <name>dfs.namenode.name.dir</name>
    <value>/Users/bng/Documnents/hDir/hdfs/name</value>
  </property>
  <property>
    <name>dfs.datanode.data.dir</name>
    <value>/Users/bng/Documnents/hDir/hdfs/data</value >
  </property>
</configuration>
</code>```

core-site.xml

```<code><?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
   <property>
      <name>fs.defaultFS</name>
      <value>hdfs://localhost/</value>
   </property>
   <property>
        <name>dfs.http.address</name>
        <value>50070</value>
    </property>
</configuration>
</code>```

mapred-site.xml

```<code><?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
     <property>
         <name>mapreduce.framework.name</name>
         <value>yarn</value>
     </property>
</configuration>
</code>```

yarn-site.xml

```<code><?xml version="1.0"?>
<configuration>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    <property>
        <name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
        <value>org.apache.hadoop.mapred.ShuffleHandler</value>
    </property>
    <property>
        <name>yarn.resourcemanager.hostname</name>
        <value>localhost</value>
    </property>
</configuration>
</code>```

And here is the screen shot of my hadoop UI:

Attached here are the execution logs as shown on STS console:

```<code>    0    [main] WARN  org.apache.hadoop.util.NativeCodeLoader  - Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
202  [main] INFO  org.apache.hadoop.conf.Configuration.deprecation  - session.id is deprecated. Instead, use dfs.metrics.session-id
203  [main] INFO  org.apache.hadoop.metrics.jvm.JvmMetrics  - Initializing JVM Metrics with processName=JobTracker, sessionId=
402  [main] WARN  org.apache.hadoop.mapreduce.JobSubmitter  - Hadoop command-line option parsing not performed. Implement the Tool interface and execute your application with ToolRunner to remedy this.
408  [main] WARN  org.apache.hadoop.mapreduce.JobSubmitter  - No job jar file set.  User classes may not be found. See Job or Job#setJar(String).
419  [main] INFO  org.apache.hadoop.mapreduce.lib.input.FileInputFormat  - Total input paths to process : 1
471  [main] INFO  org.apache.hadoop.mapreduce.JobSubmitter  - number of splits:1
593  [main] INFO  org.apache.hadoop.mapreduce.JobSubmitter  - Submitting tokens for job: job_local1149743576_0001
764  [main] INFO  org.apache.hadoop.mapreduce.Job  - The url to track the job: http://localhost:8080/
766  [Thread-10] INFO  org.apache.hadoop.mapred.LocalJobRunner  - OutputCommitter set in config null
766  [main] INFO  org.apache.hadoop.mapreduce.Job  - Running job: job_local1149743576_0001
774  [Thread-10] INFO  org.apache.hadoop.mapred.LocalJobRunner  - OutputCommitter is org.apache.hadoop.mapreduce.lib.output.FileOutputCommitter
815  [Thread-10] INFO  org.apache.hadoop.mapred.LocalJobRunner  - Waiting for map tasks
816  [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.LocalJobRunner  - Starting task: attempt_local1149743576_0001_m_000000_0
859  [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.yarn.util.ProcfsBasedProcessTree  - ProcfsBasedProcessTree currently is supported only on Linux.
860  [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.Task  -  Using ResourceCalculatorProcessTree : null
865  [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - Processing split: file:/Users/bng/Downloads/hadoop-2.6.4/files/input.txt:0+366
995  [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - (EQUATOR) 0 kvi 26214396(104857584)
995  [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - mapreduce.task.io.sort.mb: 100
995  [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - soft limit at 83886080
998  [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - bufstart = 0; bufvoid = 104857600
998  [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - kvstart = 26214396; length = 6553600
1003 [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - Map output collector class = org.apache.hadoop.mapred.MapTask$MapOutputBuffer
1010 [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.LocalJobRunner  -
1011 [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - Starting flush of map output
1011 [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - Spilling map output
1011 [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - bufstart = 0; bufend = 594; bufvoid = 104857600
1011 [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - kvstart = 26214396(104857584); kvend = 26214172(104856688); length = 225/6553600
1020 [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - Finished spill 0
1024 [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.Task  - Task:attempt_local1149743576_0001_m_000000_0 is done. And is in the process of committing
1032 [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.LocalJobRunner  - map
1032 [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.Task  - Task 'attempt_local1149743576_0001_m_000000_0' done.
1033 [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.LocalJobRunner  - Finishing task: attempt_local1149743576_0001_m_000000_0
1033 [Thread-10] INFO  org.apache.hadoop.mapred.LocalJobRunner  - map task executor complete.
1035 [Thread-10] INFO  org.apache.hadoop.mapred.LocalJobRunner  - Waiting for reduce tasks
1035 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.LocalJobRunner  - Starting task: attempt_local1149743576_0001_r_000000_0
1041 [pool-3-thread-1] INFO  org.apache.hadoop.yarn.util.ProcfsBasedProcessTree  - ProcfsBasedProcessTree currently is supported only on Linux.
1041 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.Task  -  Using ResourceCalculatorProcessTree : null
1044 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.ReduceTask  - Using ShuffleConsumerPlugin: org.apache.hadoop.mapreduce.task.reduce.Shuffle@6a57da8b
1058 [pool-3-thread-1] INFO  org.apache.hadoop.mapreduce.task.reduce.MergeManagerImpl  - MergerManager: memoryLimit=1336252800, maxSingleShuffleLimit=334063200, mergeThreshold=881926912, ioSortFactor=10, memToMemMergeOutputsThreshold=10
1060 [EventFetcher for fetching Map Completion Events] INFO  org.apache.hadoop.mapreduce.task.reduce.EventFetcher  - attempt_local1149743576_0001_r_000000_0 Thread started: EventFetcher for fetching Map Completion Events
1092 [localfetcher#1] INFO  org.apache.hadoop.mapreduce.task.reduce.LocalFetcher  - localfetcher#1 about to shuffle output of map attempt_local1149743576_0001_m_000000_0 decomp: 710 len: 714 to MEMORY
1108 [localfetcher#1] INFO  org.apache.hadoop.mapreduce.task.reduce.InMemoryMapOutput  - Read 710 bytes from map-output for attempt_local1149743576_0001_m_000000_0
1141 [localfetcher#1] INFO  org.apache.hadoop.mapreduce.task.reduce.MergeManagerImpl  - closeInMemoryFile -> map-output of size: 710, inMemoryMapOutputs.size() -> 1, commitMemory -> 0, usedMemory ->710
1142 [EventFetcher for fetching Map Completion Events] INFO  org.apache.hadoop.mapreduce.task.reduce.EventFetcher  - EventFetcher is interrupted.. Returning
1143 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.LocalJobRunner  - 1 / 1 copied.
1143 [pool-3-thread-1] INFO  org.apache.hadoop.mapreduce.task.reduce.MergeManagerImpl  - finalMerge called with 1 in-memory map-outputs and 0 on-disk map-outputs
1160 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.Merger  - Merging 1 sorted segments
1160 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.Merger  - Down to the last merge-pass, with 1 segments left of total size: 702 bytes
1162 [pool-3-thread-1] INFO  org.apache.hadoop.mapreduce.task.reduce.MergeManagerImpl  - Merged 1 segments, 710 bytes to disk to satisfy reduce memory limit
1163 [pool-3-thread-1] INFO  org.apache.hadoop.mapreduce.task.reduce.MergeManagerImpl  - Merging 1 files, 714 bytes from disk
1165 [pool-3-thread-1] INFO  org.apache.hadoop.mapreduce.task.reduce.MergeManagerImpl  - Merging 0 segments, 0 bytes from memory into reduce
1165 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.Merger  - Merging 1 sorted segments
1166 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.Merger  - Down to the last merge-pass, with 1 segments left of total size: 702 bytes
1167 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.LocalJobRunner  - 1 / 1 copied.
1186 [pool-3-thread-1] INFO  org.apache.hadoop.conf.Configuration.deprecation  - mapred.skip.on is deprecated. Instead, use mapreduce.job.skiprecords
1193 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.Task  - Task:attempt_local1149743576_0001_r_000000_0 is done. And is in the process of committing
1195 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.LocalJobRunner  - 1 / 1 copied.
1195 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.Task  - Task attempt_local1149743576_0001_r_000000_0 is allowed to commit now
1196 [pool-3-thread-1] INFO  org.apache.hadoop.mapreduce.lib.output.FileOutputCommitter  - Saved output of task 'attempt_local1149743576_0001_r_000000_0' to file:/Users/bng/Downloads/hadoop-2.6.4/files/output/_temporary/0/task_local1149743576_0001_r_000000
1197 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.LocalJobRunner  - reduce > reduce
1197 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.Task  - Task 'attempt_local1149743576_0001_r_000000_0' done.
1197 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.LocalJobRunner  - Finishing task: attempt_local1149743576_0001_r_000000_0
1197 [Thread-10] INFO  org.apache.hadoop.mapred.LocalJobRunner  - reduce task executor complete.
1772 [main] INFO  org.apache.hadoop.mapreduce.Job  - Job job_local1149743576_0001 running in uber mode : false
1774 [main] INFO  org.apache.hadoop.mapreduce.Job  -  map 100% reduce 100%
1775 [main] INFO  org.apache.hadoop.mapreduce.Job  - Job job_local1149743576_0001 completed successfully
1784 [main] INFO  org.apache.hadoop.mapreduce.Job  - Counters: 30
    File System Counters
        FILE: Number of bytes read=2542
        FILE: Number of bytes written=495530
        FILE: Number of read operations=0
        FILE: Number of large read operations=0
        FILE: Number of write operations=0
    Map-Reduce Framework
        Map input records=1
        Map output records=57
        Map output bytes=594
        Map output materialized bytes=714
        Input split bytes=119
        Combine input records=0
        Combine output records=0
        Reduce input groups=47
        Reduce shuffle bytes=714
        Reduce input records=57
        Reduce output records=47
        Spilled Records=114
        Shuffled Maps =1
        Failed Shuffles=0
        Merged Map outputs=1
        GC time elapsed (ms)=10
        Total committed heap usage (bytes)=468713472
    Shuffle Errors
        BAD_ID=0
        CONNECTION=0
        IO_ERROR=0
        WRONG_LENGTH=0
        WRONG_MAP=0
        WRONG_REDUCE=0
    File Input Format Counters
        Bytes Read=366
    File Output Format Counters
        Bytes Written=430
Job was successful
</code>```

Please suggest what going wrong here.

答:
The problem was with the job configuration when running through STS/eclipse.
So added the Job Configuration inside the run method and configured the yarn resource manager and defaultFS as follows:

```<code>public int run(String[] args) throws Exception {
    if (args.length != 2) {
        System.err.printf("Usage: %s needs two arguments <input> <output> files\n",
                getClass().getSimpleName());
        return -1;
    }
    Configuration configuration  = getConf();

    configuration.set("fs.defaultFS", "hdfs://172.20.12.168");
    configuration.set("mapreduce.jobtracker.address", "localhost:54311");
    configuration.set("mapreduce.framework.name", "yarn");
    configuration.set("yarn.resourcemanager.address", "127.0.0.1:8032");

    //Initialize the Hadoop job and set the jar as well as the name of the Job
    Job job = new Job();
    job.setJarByClass(WordCount.class);
    job.setJobName("WordCounter");

    //Add input and output file paths to job based on the arguments passed
    FileInputFormat.addInputPath(job, new Path(args[0]));
    FileOutputFormat.setOutputPath(job, new Path(args[1]));

    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(IntWritable.class);
    job.setOutputFormatClass(TextOutputFormat.class);

    //Set the MapClass and ReduceClass in the job
    job.setMapperClass(MapClass.class);
    job.setReducerClass(ReduceClass.class);

    //Wait for the job to complete and print if the job was successful or not
    int returnValue = job.waitForCompletion(true) ? 0:1;

    if(job.isSuccessful()) {
        System.out.println("Job was successful");
    } else if(!job.isSuccessful()) {
        System.out.println("Job was not successful");
    }

    return returnValue;
}
</code>```

Now, getting the job tab and job details and job history after making the above changes.

Body:
I am working with the Hadoop Map-Reduce API and exceuting a simple task to calculate the highest templeratures in year as specified through a large input file of arounf 20MB.

Everything is working fine, viz Mapper tasks are working fine, Reducer tasks are working fine and output file is also generated fine.

But the problem is that, i could not see anything on the Hadoop UI page, neither the Job tab, nor the Job Progress and not even the Job History.

Here is my wordcound java file:

import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

public class WordCount extends Configured implements Tool{

    /**
     * Main function which calls the run method and passes the args using ToolRunner
     * @param args Two arguments input and output file paths
     * @throws Exception
     */
    public static void main(String[] args) throws Exception{
        int exitCode = ToolRunner.run(new WordCount(), args);
        System.exit(exitCode);
    }

    /**
     * Run method which schedules the Hadoop Job
     * @param args Arguments passed in main function
     */
    public int run(String[] args) throws Exception {
        if (args.length != 2) {
            System.err.printf("Usage: %s needs two arguments <input> <output> files\n",
                    getClass().getSimpleName());
            return -1;
        }

        //Initialize the Hadoop job and set the jar as well as the name of the Job
        Job job = new Job();
        job.setJarByClass(WordCount.class);
        job.setJobName("WordCounter");

        //Add input and output file paths to job based on the arguments passed
        FileInputFormat.addInputPath(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);
        job.setOutputFormatClass(TextOutputFormat.class);

        //Set the MapClass and ReduceClass in the job
        job.setMapperClass(MapClass.class);
        job.setReducerClass(ReduceClass.class);

        //Wait for the job to complete and print if the job was successful or not
        int returnValue = job.waitForCompletion(true) ? 0:1;

        if(job.isSuccessful()) {
            System.out.println("Job was successful");
        } else if(!job.isSuccessful()) {
            System.out.println("Job was not successful");
        }

        return returnValue;
    }
}

Here are my hadoop configuration files:

hdfs-site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<configuration>
  <property>
    <name>dfs.replication</name>
    <value>1</value>
  </property>

  <property>
    <name>dfs.namenode.name.dir</name>
    <value>/Users/bng/Documnents/hDir/hdfs/name</value>
  </property>
  <property>
    <name>dfs.datanode.data.dir</name>
    <value>/Users/bng/Documnents/hDir/hdfs/data</value >
  </property>
</configuration>

core-site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
   <property>
      <name>fs.defaultFS</name>
      <value>hdfs://localhost/</value>
   </property>
   <property>
        <name>dfs.http.address</name>
        <value>50070</value>
    </property>
</configuration>

mapred-site.xml

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
     <property>
         <name>mapreduce.framework.name</name>
         <value>yarn</value>
     </property>
</configuration>

yarn-site.xml

<?xml version="1.0"?>
<configuration>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    <property>
        <name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
        <value>org.apache.hadoop.mapred.ShuffleHandler</value>
    </property>
    <property>
        <name>yarn.resourcemanager.hostname</name>
        <value>localhost</value>
    </property>
</configuration>

And here is the screen shot of my hadoop UI:

Attached here are the execution logs as shown on STS console:

    0    [main] WARN  org.apache.hadoop.util.NativeCodeLoader  - Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
202  [main] INFO  org.apache.hadoop.conf.Configuration.deprecation  - session.id is deprecated. Instead, use dfs.metrics.session-id
203  [main] INFO  org.apache.hadoop.metrics.jvm.JvmMetrics  - Initializing JVM Metrics with processName=JobTracker, sessionId=
402  [main] WARN  org.apache.hadoop.mapreduce.JobSubmitter  - Hadoop command-line option parsing not performed. Implement the Tool interface and execute your application with ToolRunner to remedy this.
408  [main] WARN  org.apache.hadoop.mapreduce.JobSubmitter  - No job jar file set.  User classes may not be found. See Job or Job#setJar(String).
419  [main] INFO  org.apache.hadoop.mapreduce.lib.input.FileInputFormat  - Total input paths to process : 1
471  [main] INFO  org.apache.hadoop.mapreduce.JobSubmitter  - number of splits:1
593  [main] INFO  org.apache.hadoop.mapreduce.JobSubmitter  - Submitting tokens for job: job_local1149743576_0001
764  [main] INFO  org.apache.hadoop.mapreduce.Job  - The url to track the job: http://localhost:8080/
766  [Thread-10] INFO  org.apache.hadoop.mapred.LocalJobRunner  - OutputCommitter set in config null
766  [main] INFO  org.apache.hadoop.mapreduce.Job  - Running job: job_local1149743576_0001
774  [Thread-10] INFO  org.apache.hadoop.mapred.LocalJobRunner  - OutputCommitter is org.apache.hadoop.mapreduce.lib.output.FileOutputCommitter
815  [Thread-10] INFO  org.apache.hadoop.mapred.LocalJobRunner  - Waiting for map tasks
816  [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.LocalJobRunner  - Starting task: attempt_local1149743576_0001_m_000000_0
859  [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.yarn.util.ProcfsBasedProcessTree  - ProcfsBasedProcessTree currently is supported only on Linux.
860  [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.Task  -  Using ResourceCalculatorProcessTree : null
865  [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - Processing split: file:/Users/bng/Downloads/hadoop-2.6.4/files/input.txt:0+366
995  [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - (EQUATOR) 0 kvi 26214396(104857584)
995  [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - mapreduce.task.io.sort.mb: 100
995  [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - soft limit at 83886080
998  [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - bufstart = 0; bufvoid = 104857600
998  [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - kvstart = 26214396; length = 6553600
1003 [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - Map output collector class = org.apache.hadoop.mapred.MapTask$MapOutputBuffer
1010 [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.LocalJobRunner  -
1011 [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - Starting flush of map output
1011 [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - Spilling map output
1011 [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - bufstart = 0; bufend = 594; bufvoid = 104857600
1011 [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - kvstart = 26214396(104857584); kvend = 26214172(104856688); length = 225/6553600
1020 [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.MapTask  - Finished spill 0
1024 [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.Task  - Task:attempt_local1149743576_0001_m_000000_0 is done. And is in the process of committing
1032 [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.LocalJobRunner  - map
1032 [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.Task  - Task 'attempt_local1149743576_0001_m_000000_0' done.
1033 [LocalJobRunner Map Task Executor #0] INFO  org.apache.hadoop.mapred.LocalJobRunner  - Finishing task: attempt_local1149743576_0001_m_000000_0
1033 [Thread-10] INFO  org.apache.hadoop.mapred.LocalJobRunner  - map task executor complete.
1035 [Thread-10] INFO  org.apache.hadoop.mapred.LocalJobRunner  - Waiting for reduce tasks
1035 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.LocalJobRunner  - Starting task: attempt_local1149743576_0001_r_000000_0
1041 [pool-3-thread-1] INFO  org.apache.hadoop.yarn.util.ProcfsBasedProcessTree  - ProcfsBasedProcessTree currently is supported only on Linux.
1041 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.Task  -  Using ResourceCalculatorProcessTree : null
1044 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.ReduceTask  - Using ShuffleConsumerPlugin: org.apache.hadoop.mapreduce.task.reduce.Shuffle@6a57da8b
1058 [pool-3-thread-1] INFO  org.apache.hadoop.mapreduce.task.reduce.MergeManagerImpl  - MergerManager: memoryLimit=1336252800, maxSingleShuffleLimit=334063200, mergeThreshold=881926912, ioSortFactor=10, memToMemMergeOutputsThreshold=10
1060 [EventFetcher for fetching Map Completion Events] INFO  org.apache.hadoop.mapreduce.task.reduce.EventFetcher  - attempt_local1149743576_0001_r_000000_0 Thread started: EventFetcher for fetching Map Completion Events
1092 [localfetcher#1] INFO  org.apache.hadoop.mapreduce.task.reduce.LocalFetcher  - localfetcher#1 about to shuffle output of map attempt_local1149743576_0001_m_000000_0 decomp: 710 len: 714 to MEMORY
1108 [localfetcher#1] INFO  org.apache.hadoop.mapreduce.task.reduce.InMemoryMapOutput  - Read 710 bytes from map-output for attempt_local1149743576_0001_m_000000_0
1141 [localfetcher#1] INFO  org.apache.hadoop.mapreduce.task.reduce.MergeManagerImpl  - closeInMemoryFile -> map-output of size: 710, inMemoryMapOutputs.size() -> 1, commitMemory -> 0, usedMemory ->710
1142 [EventFetcher for fetching Map Completion Events] INFO  org.apache.hadoop.mapreduce.task.reduce.EventFetcher  - EventFetcher is interrupted.. Returning
1143 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.LocalJobRunner  - 1 / 1 copied.
1143 [pool-3-thread-1] INFO  org.apache.hadoop.mapreduce.task.reduce.MergeManagerImpl  - finalMerge called with 1 in-memory map-outputs and 0 on-disk map-outputs
1160 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.Merger  - Merging 1 sorted segments
1160 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.Merger  - Down to the last merge-pass, with 1 segments left of total size: 702 bytes
1162 [pool-3-thread-1] INFO  org.apache.hadoop.mapreduce.task.reduce.MergeManagerImpl  - Merged 1 segments, 710 bytes to disk to satisfy reduce memory limit
1163 [pool-3-thread-1] INFO  org.apache.hadoop.mapreduce.task.reduce.MergeManagerImpl  - Merging 1 files, 714 bytes from disk
1165 [pool-3-thread-1] INFO  org.apache.hadoop.mapreduce.task.reduce.MergeManagerImpl  - Merging 0 segments, 0 bytes from memory into reduce
1165 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.Merger  - Merging 1 sorted segments
1166 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.Merger  - Down to the last merge-pass, with 1 segments left of total size: 702 bytes
1167 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.LocalJobRunner  - 1 / 1 copied.
1186 [pool-3-thread-1] INFO  org.apache.hadoop.conf.Configuration.deprecation  - mapred.skip.on is deprecated. Instead, use mapreduce.job.skiprecords
1193 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.Task  - Task:attempt_local1149743576_0001_r_000000_0 is done. And is in the process of committing
1195 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.LocalJobRunner  - 1 / 1 copied.
1195 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.Task  - Task attempt_local1149743576_0001_r_000000_0 is allowed to commit now
1196 [pool-3-thread-1] INFO  org.apache.hadoop.mapreduce.lib.output.FileOutputCommitter  - Saved output of task 'attempt_local1149743576_0001_r_000000_0' to file:/Users/bng/Downloads/hadoop-2.6.4/files/output/_temporary/0/task_local1149743576_0001_r_000000
1197 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.LocalJobRunner  - reduce > reduce
1197 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.Task  - Task 'attempt_local1149743576_0001_r_000000_0' done.
1197 [pool-3-thread-1] INFO  org.apache.hadoop.mapred.LocalJobRunner  - Finishing task: attempt_local1149743576_0001_r_000000_0
1197 [Thread-10] INFO  org.apache.hadoop.mapred.LocalJobRunner  - reduce task executor complete.
1772 [main] INFO  org.apache.hadoop.mapreduce.Job  - Job job_local1149743576_0001 running in uber mode : false
1774 [main] INFO  org.apache.hadoop.mapreduce.Job  -  map 100% reduce 100%
1775 [main] INFO  org.apache.hadoop.mapreduce.Job  - Job job_local1149743576_0001 completed successfully
1784 [main] INFO  org.apache.hadoop.mapreduce.Job  - Counters: 30
    File System Counters
        FILE: Number of bytes read=2542
        FILE: Number of bytes written=495530
        FILE: Number of read operations=0
        FILE: Number of large read operations=0
        FILE: Number of write operations=0
    Map-Reduce Framework
        Map input records=1
        Map output records=57
        Map output bytes=594
        Map output materialized bytes=714
        Input split bytes=119
        Combine input records=0
        Combine output records=0
        Reduce input groups=47
        Reduce shuffle bytes=714
        Reduce input records=57
        Reduce output records=47
        Spilled Records=114
        Shuffled Maps =1
        Failed Shuffles=0
        Merged Map outputs=1
        GC time elapsed (ms)=10
        Total committed heap usage (bytes)=468713472
    Shuffle Errors
        BAD_ID=0
        CONNECTION=0
        IO_ERROR=0
        WRONG_LENGTH=0
        WRONG_MAP=0
        WRONG_REDUCE=0
    File Input Format Counters
        Bytes Read=366
    File Output Format Counters
        Bytes Written=430
Job was successful

Please suggest what going wrong here.

Body:
The problem was with the job configuration when running through STS/eclipse.
So added the Job Configuration inside the run method and configured the yarn resource manager and defaultFS as follows:

public int run(String[] args) throws Exception {
    if (args.length != 2) {
        System.err.printf("Usage: %s needs two arguments <input> <output> files\n",
                getClass().getSimpleName());
        return -1;
    }
    Configuration configuration  = getConf();

    configuration.set("fs.defaultFS", "hdfs://172.20.12.168");
    configuration.set("mapreduce.jobtracker.address", "localhost:54311");
    configuration.set("mapreduce.framework.name", "yarn");
    configuration.set("yarn.resourcemanager.address", "127.0.0.1:8032");

    //Initialize the Hadoop job and set the jar as well as the name of the Job
    Job job = new Job();
    job.setJarByClass(WordCount.class);
    job.setJobName("WordCounter");

    //Add input and output file paths to job based on the arguments passed
    FileInputFormat.addInputPath(job, new Path(args[0]));
    FileOutputFormat.setOutputPath(job, new Path(args[1]));

    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(IntWritable.class);
    job.setOutputFormatClass(TextOutputFormat.class);

    //Set the MapClass and ReduceClass in the job
    job.setMapperClass(MapClass.class);
    job.setReducerClass(ReduceClass.class);

    //Wait for the job to complete and print if the job was successful or not
    int returnValue = job.waitForCompletion(true) ? 0:1;

    if(job.isSuccessful()) {
        System.out.println("Job was successful");
    } else if(!job.isSuccessful()) {
        System.out.println("Job was not successful");
    }

    return returnValue;
}

Now, getting the job tab and job details and job history after making the above changes.


来源: stackexchange

问:
No touches being triggered!
OK, I guess my previous question wasn't in detail.
I'm providing more details.

Before posting full source code I have to ask if my question:
My question is Why the following program doesn't call touchesBegan, touchesMoved and touchesEnded? It used to work in previous iOS SDK. My current xcode version is 3.2.5

One comment: The following code dose call all touches if you run it against iPad Simulator. So that's very odd why iPhone simulator and the actual device don't respond to the problem.

main.m

```<code>#import <UIKit/UIKit.h>
int main(int argc, char *argv[]) {

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate");
    [pool release];
    return retVal;
}
</code>```

AppDelegate.h

```<code>#import <UIKit/UIKit.h>
@class GLView;

@interface AppDelegate : NSObject <UIApplicationDelegate>
{
    UIWindow*   mp_window;
    GLView*     mp_viewController;
}

@end
</code>```

AppDelegate.mm

```<code>#import "AppDelegate.h"
#import "GLView.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    CGRect screenBounds = [[UIScreen mainScreen] bounds];

    mp_window = [[UIWindow alloc] initWithFrame: screenBounds];
    mp_viewController = [[GLView alloc] initWithFrame: screenBounds];

    [mp_window addSubview: mp_viewController];
    [mp_window makeKeyAndVisible];

    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{}

- (void)applicationDidBecomeActive:(UIApplication *)application
{}

- (void)applicationWillTerminate:(UIApplication *)application
{}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Handle any background procedures not related to animation here.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Handle any foreground procedures not related to animation here.
}

- (void)dealloc
{
    [mp_viewController release];
    [mp_window release];

    [super dealloc];
}

@end
</code>```

GLView.h

```<code>#import <OpenGLES/EAGL.h>
#import <QuartzCore/QuartzCore.h>

@interface GLView : UIView <UIAccelerometerDelegate>
{
@private
    EAGLContext*        mp_context;
}

- (void) gameLoop;

- (void) drawView: (float) interpolation;

- (void)touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event;
- (void)touchesMoved: (NSSet*) touches withEvent: (UIEvent*) event;
- (void)touchesEnded: (NSSet*) touches withEvent: (UIEvent*) event;

- (void)accelerometer: (UIAccelerometer *) accelerometer
        didAccelerate: (UIAcceleration *) acceleration;

@end
</code>```

GLView.mm

```<code>#import "GLView.h"
#import <OpenGLES/ES2/gl.h>

@implementation GLView

+ (Class) layerClass
{
    return [CAEAGLLayer class];
}

- (id) initWithFrame: (CGRect) frame
{
    if (self = [super initWithFrame: frame])
    {
        CAEAGLLayer* eaglLayer = (CAEAGLLayer*) super.layer;
        eaglLayer.opaque = YES;

        EAGLRenderingAPI api = kEAGLRenderingAPIOpenGLES1;
        mp_context = [[EAGLContext alloc] initWithAPI: api];

        if (!mp_context || ![EAGLContext setCurrentContext: mp_context])
        {
            [self release];
            return nil;
        }

        [mp_context renderbufferStorage: GL_RENDERBUFFER
                           fromDrawable: eaglLayer];

        //TODO: to setup the size of frame for render
        //////

        //acc
        [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(0.1f)];
        [[UIAccelerometer sharedAccelerometer] setDelegate:self];

        //multi - touch
        [self setUserInteractionEnabled:YES];
        [self setMultipleTouchEnabled:YES];

        [self performSelectorOnMainThread:@selector(gameLoop)
                               withObject:nil waitUntilDone:NO];
    }

    return self;
}

- (void) gameLoop
{
    while(1)
    {
            //Get all touches
        while(CFRunLoopRunInMode(kCFRunLoopDefaultMode,
                     0.002f,
                     TRUE) == kCFRunLoopRunHandledSource);
            //render scene
            [drawView 1.0f];
    }
}

- (void) drawView: (float) interpolation
{
    //TODO: adding render image here
    //NSLog(@"Render: %f", interpolation);
    [mp_context presentRenderbuffer: GL_RENDERBUFFER];
}

- (void) dealloc
{

    if ([EAGLContext currentContext] == mp_context)
        [EAGLContext setCurrentContext: nil];

    [mp_context release];
    //TODO: relese all objects here
    [super dealloc];
}

- (void)touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event
{
    int hash;
    CGPoint points;
    for(UITouch * touch in touches)
    {
        hash = [touch hash];
        points = [touch locationInView: self];
        NSLog(@"Touch Began: %d, %f, %f", hash, points.x, points.y);
    }
}

- (void)touchesMoved: (NSSet*) touches withEvent: (UIEvent*) event
{
    int hash;
    CGPoint points;
    for(UITouch * touch in touches)
    {
        hash = [touch hash];
        points = [touch locationInView: self];
        NSLog(@"Touch Moved: %d, %f, %f", hash, points.x, points.y);
    }
}

- (void)touchesEnded: (NSSet*) touches withEvent: (UIEvent*) event
{
    int hash;
    CGPoint points;
    for(UITouch * touch in touches)
    {
        hash = [touch hash];
        points = [touch locationInView: self];
        NSLog(@"Touch Ended: %d, %f, %f", hash, points.x, points.y);
    }
}

- (void) accelerometer: (UIAccelerometer *) accelerometer
         didAccelerate: (UIAcceleration *) acceleration
{
    NSLog(@"Accelerometer: (%f, %f, %f)",
          acceleration.x,
          acceleration.y,
          acceleration.z );
}

@end
</code>```

This is only a test case. my main concern is why with new SDK, touches won't be called? Please don't tell me I have to use NSTimer or other timers. I did work before I install the new SDK. I'm just wondering if anyone can see any problem in that source code other than that.

Thanks,
Memphis

答:
I don't know with certainty what your problem is.  I do note, however, that you don't have a view controller--while your UIApplicationDelegate subclass has a mp_viewController member, it's a UIView instead of a UIViewController.  It is possible that this is the source of your problem.

I suggest adding a UIViewController associated with your view and assigning it to the application delegate's rootViewController property.

ContentLicense: CC BY-SA 2.5

Title: No touches being triggered!

Body:
OK, I guess my previous question wasn't in detail.
I'm providing more details.

Before posting full source code I have to ask if my question:
My question is Why the following program doesn't call touchesBegan, touchesMoved and touchesEnded? It used to work in previous iOS SDK. My current xcode version is 3.2.5

One comment: The following code dose call all touches if you run it against iPad Simulator. So that's very odd why iPhone simulator and the actual device don't respond to the problem.

main.m

#import <UIKit/UIKit.h>
int main(int argc, char *argv[]) {

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate");
    [pool release];
    return retVal;
}

AppDelegate.h

#import <UIKit/UIKit.h>
@class GLView;

@interface AppDelegate : NSObject <UIApplicationDelegate>
{
    UIWindow*   mp_window;
    GLView*     mp_viewController;
}

@end

AppDelegate.mm

#import "AppDelegate.h"
#import "GLView.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    CGRect screenBounds = [[UIScreen mainScreen] bounds];

    mp_window = [[UIWindow alloc] initWithFrame: screenBounds];
    mp_viewController = [[GLView alloc] initWithFrame: screenBounds];

    [mp_window addSubview: mp_viewController];
    [mp_window makeKeyAndVisible];

    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{}

- (void)applicationDidBecomeActive:(UIApplication *)application
{}

- (void)applicationWillTerminate:(UIApplication *)application
{}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Handle any background procedures not related to animation here.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Handle any foreground procedures not related to animation here.
}

- (void)dealloc
{
    [mp_viewController release];
    [mp_window release];

    [super dealloc];
}

@end

GLView.h

#import <OpenGLES/EAGL.h>
#import <QuartzCore/QuartzCore.h>

@interface GLView : UIView <UIAccelerometerDelegate>
{
@private
    EAGLContext*        mp_context;
}

- (void) gameLoop;

- (void) drawView: (float) interpolation;

- (void)touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event;
- (void)touchesMoved: (NSSet*) touches withEvent: (UIEvent*) event;
- (void)touchesEnded: (NSSet*) touches withEvent: (UIEvent*) event;

- (void)accelerometer: (UIAccelerometer *) accelerometer
        didAccelerate: (UIAcceleration *) acceleration;

@end

GLView.mm

#import "GLView.h"
#import <OpenGLES/ES2/gl.h>

@implementation GLView

+ (Class) layerClass
{
    return [CAEAGLLayer class];
}

- (id) initWithFrame: (CGRect) frame
{
    if (self = [super initWithFrame: frame])
    {
        CAEAGLLayer* eaglLayer = (CAEAGLLayer*) super.layer;
        eaglLayer.opaque = YES;

        EAGLRenderingAPI api = kEAGLRenderingAPIOpenGLES1;
        mp_context = [[EAGLContext alloc] initWithAPI: api];

        if (!mp_context || ![EAGLContext setCurrentContext: mp_context])
        {
            [self release];
            return nil;
        }

        [mp_context renderbufferStorage: GL_RENDERBUFFER
                           fromDrawable: eaglLayer];

        //TODO: to setup the size of frame for render
        //////

        //acc
        [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(0.1f)];
        [[UIAccelerometer sharedAccelerometer] setDelegate:self];

        //multi - touch
        [self setUserInteractionEnabled:YES];
        [self setMultipleTouchEnabled:YES];

        [self performSelectorOnMainThread:@selector(gameLoop)
                               withObject:nil waitUntilDone:NO];
    }

    return self;
}

- (void) gameLoop
{
    while(1)
    {
            //Get all touches
        while(CFRunLoopRunInMode(kCFRunLoopDefaultMode,
                     0.002f,
                     TRUE) == kCFRunLoopRunHandledSource);
            //render scene
            [drawView 1.0f];
    }
}

- (void) drawView: (float) interpolation
{
    //TODO: adding render image here
    //NSLog(@"Render: %f", interpolation);
    [mp_context presentRenderbuffer: GL_RENDERBUFFER];
}

- (void) dealloc
{

    if ([EAGLContext currentContext] == mp_context)
        [EAGLContext setCurrentContext: nil];

    [mp_context release];
    //TODO: relese all objects here
    [super dealloc];
}

- (void)touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event
{
    int hash;
    CGPoint points;
    for(UITouch * touch in touches)
    {
        hash = [touch hash];
        points = [touch locationInView: self];
        NSLog(@"Touch Began: %d, %f, %f", hash, points.x, points.y);
    }
}

- (void)touchesMoved: (NSSet*) touches withEvent: (UIEvent*) event
{
    int hash;
    CGPoint points;
    for(UITouch * touch in touches)
    {
        hash = [touch hash];
        points = [touch locationInView: self];
        NSLog(@"Touch Moved: %d, %f, %f", hash, points.x, points.y);
    }
}

- (void)touchesEnded: (NSSet*) touches withEvent: (UIEvent*) event
{
    int hash;
    CGPoint points;
    for(UITouch * touch in touches)
    {
        hash = [touch hash];
        points = [touch locationInView: self];
        NSLog(@"Touch Ended: %d, %f, %f", hash, points.x, points.y);
    }
}

- (void) accelerometer: (UIAccelerometer *) accelerometer
         didAccelerate: (UIAcceleration *) acceleration
{
    NSLog(@"Accelerometer: (%f, %f, %f)",
          acceleration.x,
          acceleration.y,
          acceleration.z );
}

@end

This is only a test case. my main concern is why with new SDK, touches won't be called? Please don't tell me I have to use NSTimer or other timers. I did work before I install the new SDK. I'm just wondering if anyone can see any problem in that source code other than that.

Thanks,
Memphis


问:
Can't Select Checkbox, Selenium WebDriver
I am unable to select a checkbox with Selenium WebDriver in Java.
I tried by Xpath but no result.
WebDriver can't click on element.
I tried with Selenium IDE - recorder, no results.

Here it is - html code for checkbox

I try:

1.

```<code>driver.findElement(By.xpath(".//form[@id='placeOrderForm1']/div[@class='terms right']/label")).click();
</code>```

2.

```<code>driver.findElement(By.id("Terms1")).click();
</code>```

3.

```<code>driver.findElement(By.cssSelector("label")).click();
</code>```

4.

```<code>driver.findElement(By.xpath("//div[3]/form/div/input")).click();
</code>```

Nothing works.
Please help.

答:
Try using JavascriptExecuter Hope this will help

```<code>WebElement element = driver.findElement(By.id("Terms1"));
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("arguments[0].click();", element );
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I am unable to select a checkbox with Selenium WebDriver in Java.
I tried by Xpath but no result.
WebDriver can't click on element.
I tried with Selenium IDE - recorder, no results.

Here it is - html code for checkbox

I try:

1.

driver.findElement(By.xpath(".//form[@id='placeOrderForm1']/div[@class='terms right']/label")).click();

2.

driver.findElement(By.id("Terms1")).click();

3.

driver.findElement(By.cssSelector("label")).click();

4.

driver.findElement(By.xpath("//div[3]/form/div/input")).click();

Nothing works.
Please help.

Body:
Try using JavascriptExecuter Hope this will help

WebElement element = driver.findElement(By.id("Terms1"));
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("arguments[0].click();", element );


问:
Android Why EditText ellipsize doesn't work?
I have added an EditText to my layout, but the ellipsize doesn't work. Can anybody help me? Thanks.</p>

```<code><EditText
        android:layout_width="match_parent"
        android:layout_margin="10dp"
        android:singleLine="true"
        android:ellipsize="end"
        android:textSize="24dp"
        android:layout_height="wrap_content" />
</code>```

答:
ellipsize maybe works only with

```<code>android:ellipsize="end"
android:singleLine="true"
</code>```

and sometimes we add one more

```<code>android:maxLines="n"
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I have added an EditText to my layout, but the ellipsize doesn't work. Can anybody help me? Thanks.

<EditText
        android:layout_width="match_parent"
        android:layout_margin="10dp"
        android:singleLine="true"
        android:ellipsize="end"
        android:textSize="24dp"
        android:layout_height="wrap_content" />

Body:
ellipsize maybe works only with

android:ellipsize="end"
android:singleLine="true"

and sometimes we add one more

android:maxLines="n"


问:
Is it possible to replace parentheses with $?
I have the following function:

```<code>digits :: Int -> [Int]
digits n = go n []
    where go num acc
            | num < 10 = num : acc
            | otherwise = go (div num 10) (mod num 10 : acc)
</code>```

Is it possible to replace the parentheses in the otherwise expression with $?

答:
The problem

You can't use $ for that. The purpose of $ is to make function application bind as un-tighly as possible, as opposed to normal function application which binds most tightly,

```<code>> :i $
($) :: (a -> b) -> a -> b
infixr 0 $
</code>```

(some irrelevant stuff removed...)

Here, infixr denotes that the operator is right associative, as opposed to infixl which denotes that the operator is left associative. 0 denotes the precedence of the operator. 0 binds least tightly and 9 binds most tightly.

If we write go $ div num 10 $ mod num 10 : acc, this is interpreted as go (div num 10 (mod num 10 : acc)), i.e: passing mod num 10 : acc as the third argument of div, and the result of applying div as the only argument to go.

Solution: the (&) operator

Instead of using the dollar sign, $, for the left hand side, you can instead use &.

```<code>> :i &
(&) :: a -> (a -> b) -> b       -- Defined in `Data.Function'
infixl 1 &
</code>```

And now we get:

```<code>import Data.Function ((&))

digits :: Int -> [Int]
digits n = go n []
    where go num acc
            | num < 10 = num : acc
            | otherwise = div num 10 & go $ mod num 10 : acc
</code>```

Solution: apply go infix

You could also use go infix:

```<code>digits :: Int -> [Int]
digits n = go n []
    where go num acc
            | num < 10 = num : acc
            | otherwise = div num 10 `go` (mod num 10 : acc)
</code>```

In this case, the parenthesis on the right hand side is needed due to (:) which is also infix and interferes with go.

Which solution to use

In my opinion, if you can use infix application without parenthesizes, do that. In the case of having a parenthesis on any side such as in: div num 10 `go` (mod num 10 : acc), it may still be warranted to use infix. This is mainly due to readability, as the average reader may not be familiar with &. This notation is (probably) not very commonly used, which is why the average reader is not very familiar with it (and so we have a cycle...).

On the usage of $$

I believe Alexey Romanov's operator, $$ is quite neat as well. Unfortunately, it suffers the same problems as & does: lack of familiarity. Hopefully, his operator can be added to Data.Function in due time and perhaps we can expand our toolbox.

Body:
I have the following function:

digits :: Int -> [Int]
digits n = go n []
    where go num acc
            | num < 10 = num : acc
            | otherwise = go (div num 10) (mod num 10 : acc)

Is it possible to replace the parentheses in the otherwise expression with $?

Body:
The problem

You can't use $ for that. The purpose of $ is to make function application bind as un-tighly as possible, as opposed to normal function application which binds most tightly,

> :i $
($) :: (a -> b) -> a -> b
infixr 0 $

(some irrelevant stuff removed...)

Here, infixr denotes that the operator is right associative, as opposed to infixl which denotes that the operator is left associative. 0 denotes the precedence of the operator. 0 binds least tightly and 9 binds most tightly.

If we write go $ div num 10 $ mod num 10 : acc, this is interpreted as go (div num 10 (mod num 10 : acc)), i.e: passing mod num 10 : acc as the third argument of div, and the result of applying div as the only argument to go.

Solution: the (&) operator

Instead of using the dollar sign, $, for the left hand side, you can instead use &.

> :i &
(&) :: a -> (a -> b) -> b       -- Defined in `Data.Function'
infixl 1 &

And now we get:

import Data.Function ((&))

digits :: Int -> [Int]
digits n = go n []
    where go num acc
            | num < 10 = num : acc
            | otherwise = div num 10 & go $ mod num 10 : acc

Solution: apply go infix

You could also use go infix:

digits :: Int -> [Int]
digits n = go n []
    where go num acc
            | num < 10 = num : acc
            | otherwise = div num 10 `go` (mod num 10 : acc)

In this case, the parenthesis on the right hand side is needed due to (:) which is also infix and interferes with go.

Which solution to use

In my opinion, if you can use infix application without parenthesizes, do that. In the case of having a parenthesis on any side such as in: div num 10 `go` (mod num 10 : acc), it may still be warranted to use infix. This is mainly due to readability, as the average reader may not be familiar with &. This notation is (probably) not very commonly used, which is why the average reader is not very familiar with it (and so we have a cycle...).

On the usage of $$

I believe Alexey Romanov's operator, $$ is quite neat as well. Unfortunately, it suffers the same problems as & does: lack of familiarity. Hopefully, his operator can be added to Data.Function in due time and perhaps we can expand our toolbox.


问:
MDX: Invalid procedure call or argument when substracting
I am struggling with the following statement:

```<code>    WITH MEMBER [Measures].[Diff Geo Volumen Artikelnummer] as

[D_Artikel].[Geo Max Volumen Artikelnummer].CurrentMember.Member_Value- --remark1
[D_Artikel].[Geo Min Volumen Artikelnummer].CurrentMember.Member_Value

SELECT non empty
{[Measures].[Menge_Artikel_Stk], [Measures].[Diff Geo Volumen Artikelnummer]} on 0,

NON EMPTY
crossjoin(
filter([D_Artikel].[Artikelnummer].[Artikelnummer],[Measures].[Diff Geo Volumen Artikelnummer]>0) , -- remark2
[D_Artikel].[Geo Max Volumen Artikelnummer].[Geo Max Volumen Artikelnummer],
[D_Artikel].[Geo Min Volumen Artikelnummer].[Geo Min Volumen Artikelnummer])
on 1
FROM [Tag_PL_Bestand_Cube_TM]
WHERE ([D_Datum].[Datum].[Tag].&[2017-06-06T00:00:00])
</code>```

1) remark1: The calculation works when replacing the substraction with an addition. Why?
2) remark2: The substraction works when not using the filter function...

Unfortunately, I want to filter and substract... Eventually I want to use Excel Pivot  to access the data and create the new measure in Excel.

The error message says: Executing the query ... Query (3, 1)
  Typenkonflikt beim Subtract-Operator. Systemfehler:  Invalid procedure
  call or argument Run complete

*Typenkonflikt = type mismatch

Instead of the Member_Value I have also tried .Value and .MemberValue

答:
This tells you line 3 is at fault: Query (3, 1)

Comments in mdx are ignored using // not like sql --

This should function better:

```<code>WITH MEMBER [Measures].[Diff Geo Volumen Artikelnummer] as
  //remark1
  [D_Artikel].[Geo Max Volumen Artikelnummer].CurrentMember.Member_Value-
  [D_Artikel].[Geo Min Volumen Artikelnummer].CurrentMember.Member_Value
...
...
</code>```

Body:
I am struggling with the following statement:

    WITH MEMBER [Measures].[Diff Geo Volumen Artikelnummer] as

[D_Artikel].[Geo Max Volumen Artikelnummer].CurrentMember.Member_Value- --remark1
[D_Artikel].[Geo Min Volumen Artikelnummer].CurrentMember.Member_Value

SELECT non empty
{[Measures].[Menge_Artikel_Stk], [Measures].[Diff Geo Volumen Artikelnummer]} on 0,

NON EMPTY
crossjoin(
filter([D_Artikel].[Artikelnummer].[Artikelnummer],[Measures].[Diff Geo Volumen Artikelnummer]>0) , -- remark2
[D_Artikel].[Geo Max Volumen Artikelnummer].[Geo Max Volumen Artikelnummer],
[D_Artikel].[Geo Min Volumen Artikelnummer].[Geo Min Volumen Artikelnummer])
on 1
FROM [Tag_PL_Bestand_Cube_TM]
WHERE ([D_Datum].[Datum].[Tag].&[2017-06-06T00:00:00])

1) remark1: The calculation works when replacing the substraction with an addition. Why?
2) remark2: The substraction works when not using the filter function...

Unfortunately, I want to filter and substract... Eventually I want to use Excel Pivot  to access the data and create the new measure in Excel.

The error message says: Executing the query ... Query (3, 1)
  Typenkonflikt beim Subtract-Operator. Systemfehler:  Invalid procedure
  call or argument Run complete

*Typenkonflikt = type mismatch

Instead of the Member_Value I have also tried .Value and .MemberValue

Body:
This tells you line 3 is at fault: Query (3, 1)

Comments in mdx are ignored using // not like sql --

This should function better:

WITH MEMBER [Measures].[Diff Geo Volumen Artikelnummer] as
  //remark1
  [D_Artikel].[Geo Max Volumen Artikelnummer].CurrentMember.Member_Value-
  [D_Artikel].[Geo Min Volumen Artikelnummer].CurrentMember.Member_Value
...
...


问:
c++ two functions do the same except one line
I dont want to duplicate my code, but I have 2 functions which do the same except 1 line.
I do want separate functions that will call a private function, that might be a template and will solve my duplicate code problem.

```<code>double EuclideanDistance::calculateDistance(const Point &p1, const Point &p2) const
{
    if (p1.getDimension()!=p2.getDimension())
        return 0;
    double sum = 0.0;
    for( size_t i = 0; i < p1.getDimension(); i++)
    {
        sum += pow( p1[i] - p2[i], 2.0);
    }
    return sqrt(sum);
}

double EuclideanDistance::calculateWeightedDistance(const Point &p1, const Point &p2, const double *weights) const
{
    if (p1.getDimension()!=p2.getDimension())
        return 0;
    double sum = 0.0;
    for( size_t i = 0; i < p1.getDimension(); i++)
    {
        sum += pow( ((p1[i] - p2[i])*weights[i]), 2.0);//here is the difference
    }
    return sqrt(sum);
}
</code>```

what do you suggest?

答:
Implement only calculateWeightedDistance fully.
and for calculateDistance call calculateWeightedDistance with weight 1.0

Body:
I dont want to duplicate my code, but I have 2 functions which do the same except 1 line.
I do want separate functions that will call a private function, that might be a template and will solve my duplicate code problem.

double EuclideanDistance::calculateDistance(const Point &p1, const Point &p2) const
{
    if (p1.getDimension()!=p2.getDimension())
        return 0;
    double sum = 0.0;
    for( size_t i = 0; i < p1.getDimension(); i++)
    {
        sum += pow( p1[i] - p2[i], 2.0);
    }
    return sqrt(sum);
}

double EuclideanDistance::calculateWeightedDistance(const Point &p1, const Point &p2, const double *weights) const
{
    if (p1.getDimension()!=p2.getDimension())
        return 0;
    double sum = 0.0;
    for( size_t i = 0; i < p1.getDimension(); i++)
    {
        sum += pow( ((p1[i] - p2[i])*weights[i]), 2.0);//here is the difference
    }
    return sqrt(sum);
}

what do you suggest?


问:
Cassandra client port enable
How to enable cassandra port to connect with BI application. Here my setup with cassandra is of multiple nodes (192.xxx.xx.01,192.xxx.xx.02,192.xxx.xx.03). In this scenario which node will be acting like master / coordinator with my application.

Although i worked with listen_address, rpc_address, broadcast_rpc_address and seeds, I opened both tcp ports 9042 and 9160.

version: 3.10

Kindly, lead me to the right direction.

答:
Cassandra uses master-less architecture.All nodes are equal in cassandra.

When you connect to one of the node that node act as co-ordinator node, any of the node can be co-ordinator.

The coordinator is selected by the driver based on the policy you have set. Common policies are DCAwareRoundRobinPolicy and TokenAware Policy.

For DCAwareRoundRobinPolicy, the driver selects the coordinator node based on its round robin policy. See more here: http://docs.datastax.com/en/drivers/java/2.1/com/datastax/driver/core/policies/DCAwareRoundRobinPolicy.html

For TokenAwarePolicy, it selects a coordinator node that has the data being queried - to reduce "hops" and latency. More info: http://docs.datastax.com/en/drivers/java/2.1/com/datastax/driver/core/policies/TokenAwarePolicy.html

native_transport_port is 9042 by default and clients use native transport by default.

Hence you should have connection from your BI to Cassandra host on port 9042.

Title: Cassandra client port enable


问:
How to prevent Sql-Injection on User-Generated Sql Queries
I have a project (private, ASP.net website, password protected with https) where one of the requirements is that the user be able to enter Sql queries that will directly query the database. I need to be able to allow these queries, while preventing them from doing damage to the database itself, and from accessing or updating data that they shouldn't be able to access/update.

I have come up with the following rules for implementation:

Use a db user that only has permission for Select Table/View and Update Table (thus any other commands like drop/alter/truncate/insert/delete will just not run).

Verify that the statement begins with the words "Select" or "Update"

Verify (using Regex) that there are no instances of semi-colons in the statement that are not surrounded by single-quotes, white space and letters. (The thought here is that the only way that they could include a second query would be to end the first with a semi-colon that is not part of an input string).

Verify (using Regex) that the user has permission to access the tables being queried/updated, included in joins, etc. This includes any subqueries. (Part of the way that this will be accomplished is that the user will be using a set of table names that do not actually exist in the database, part of the query parsing will be to substitute in the correct corresponding table names into the query).

Am I missing anything?

The goal is that the users be able to query/update tables to which they have access in any way that they see fit, and to prevent any accidental or malicious attempts to damage the db. (And since a requirement is that the user generate the sql, I have no way to parametrize the query or sanitize it using any built-in tools that I know of).

答:
This is a terribly bad practice. I would create a handful of stored procedures to handle everything you'd want to do, even the more advanced queries. Present them to the user, let them pick the one they want, and pass your parameters.

The answer above mine is also extremely good.

OwnerDisplayName: Yaakov Ellis

LastEditorDisplayName: Yaakov Ellis

OwnerDisplayName: Bbetances


问:
How do I change image on hover of  that the img is in - in jQuery?
You can see the implementation here http://jsfiddle.net/xNSFA/

Right now, when you hover over the cell, it changes some of the characteristics. But the image doesn't change. The image only changes when you hover over the image specifically.

How do I get the image to change with everything else?

By the way, it doesn't HAVE to be done in jQuery. If there is a nice elegant way to do this in CSS, I would love that. But I just assumed it was impossible to do - because of the image manipulation and I didn't want to set the background of the  to be that image. I want the image inside the cell.

Thanks.

答:
```<code>td:hover img {
     //css attributes to change
}
</code>```

OR to change the source

```<code>$("table td").hover(function() {
                 this.src = $('img', this).src.replace('-grey.png', '-blk.png');
                }, function() {
                 this.src = $('img', this).src.replace('-blk.png', '-grey.png');
    });
</code>```

The image source can't be changed via CSS, but you can change the background image, or background position.

Title: How do I change image on hover of <td> that the img is in - in jQuery?

Body:
td:hover img {
     //css attributes to change
}

OR to change the source

$("table td").hover(function() {
                 this.src = $('img', this).src.replace('-grey.png', '-blk.png');
                }, function() {
                 this.src = $('img', this).src.replace('-blk.png', '-grey.png');
    });

The image source can't be changed via CSS, but you can change the background image, or background position.


问:
How can I change my cURL call to recognise more than 1 parameter?
I want to make the following curl call to get an access token:

```<code>curl -k -XPOST --user "{user}" {url}/access_token -d 'grant_type=authorization_code&code={code}&redirect_uri={uri}'
</code>```

However, I get the following error statement:

```<code>'code' is not recognized as ane internal or external command, operable program or batch file.
'redirect_uri' is not recognized as ane internal or external command, operable program or batch file.
</code>```

When I check the trace, I see that the body only contains this: 'grant_type=authorization_code

What can I do to make sure all the parameters get passed?

答:
```<code>curl -X "POST" "{url}/access_token" \
 --user "{user}" \
 -H "Content-Type: application/x-www-form-urlencoded" \
 --data-urlencode "code={code}" \
 --data-urlencode "redirect_uri={uri}" \
 --data-urlencode "grant_type=authorization_code"
</code>```

I hope this helps

Body:
I want to make the following curl call to get an access token:

curl -k -XPOST --user "{user}" {url}/access_token -d 'grant_type=authorization_code&code={code}&redirect_uri={uri}'

However, I get the following error statement:

'code' is not recognized as ane internal or external command, operable program or batch file.
'redirect_uri' is not recognized as ane internal or external command, operable program or batch file.

When I check the trace, I see that the body only contains this: 'grant_type=authorization_code

What can I do to make sure all the parameters get passed?

Body:
curl -X "POST" "{url}/access_token" \
 --user "{user}" \
 -H "Content-Type: application/x-www-form-urlencoded" \
 --data-urlencode "code={code}" \
 --data-urlencode "redirect_uri={uri}" \
 --data-urlencode "grant_type=authorization_code"

I hope this helps


问:
I would like to fadein/fadeout a list of terms from an array only once
I am trying to make some titles that will fade in and out of a landing page once and then not repeat. Here is the code I have been trying to use. Of course it repeats forever. I am a beginner and was trying to include a counter variable that would get the index number of the last item in the array, and when this number is reached, stop repeating. This way the the texts can be added to without needed to update the nth item number. </p>

```<code>// after the last title in the array has been displayed, stop loop
// +++++++++++++++++++ changeTitle

var titles = ["title zero", "title one", "title two", "title three",
    "title four", "title n"
];

function changeTitle() {
    var ct = $("#title").data("term") || 0;

    $("#title").data("term", ct == titles.length - 1 ? 0 : ct + 1)
               .text(titles[ct])
               .fadeIn(200)
               .delay(500)
               .fadeOut(200, changeTitle);
}
$(changeTitle);
</code>```

答:
Somehwhere in your html you should open a script tag and execute this once the document is ready. That is a commonJQuery Pattern

```<code><script>
    $(document).ready(function() {
        changeTitle();
    });
</script>
</code>```

This should do the job. Since you're using jQuery anyway this does not introduce any new dependencies.

Body:
I am trying to make some titles that will fade in and out of a landing page once and then not repeat. Here is the code I have been trying to use. Of course it repeats forever. I am a beginner and was trying to include a counter variable that would get the index number of the last item in the array, and when this number is reached, stop repeating. This way the the texts can be added to without needed to update the nth item number.

// after the last title in the array has been displayed, stop loop
// +++++++++++++++++++ changeTitle

var titles = ["title zero", "title one", "title two", "title three",
    "title four", "title n"
];

function changeTitle() {
    var ct = $("#title").data("term") || 0;

    $("#title").data("term", ct == titles.length - 1 ? 0 : ct + 1)
               .text(titles[ct])
               .fadeIn(200)
               .delay(500)
               .fadeOut(200, changeTitle);
}
$(changeTitle);

Body:
Somehwhere in your html you should open a script tag and execute this once the document is ready. That is a commonJQuery Pattern

<script>
    $(document).ready(function() {
        changeTitle();
    });
</script>

This should do the job. Since you're using jQuery anyway this does not introduce any new dependencies.


问:
page-break-after / page-break-after property for div elements
My html is having this kind of structure :

```<code><div>
    <div class="pagebr">content1</div>
    <div class="pagebr">content2</div>
    <div class="pagebr">content3</div>
    <div class="pagebr">content4</div>
    <div class="pagebr">content5</div>
    <div class="pagebr">content6</div>
    <div class="pagebr">content7</div>
</div>
</code>```

All the inner Div elements are coming dynamically. Sometimes there will be one or two div or may be all. It is not fixed. But total are 7.
When I write class -

```<code>div.pagebr
{
    page-break-after:always;
}
</code>```

Every div move to next new page creating empty space after div element.
page-break-before:always; does the same and page-break-after:auto;  is not working anymore.

How should I add class for the Div elements, so that they can be fit on each page without breaking? Or is there any alternate solution?

Any help is appreciated.
Thanks.

答:
Page content can not be fit in a page in case of dynamic elements. If you want avoid page break inside your div you can specify page-break-inside:avoid; like following example

div.pagebr
{
    page-break-inside:avoid;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div>
    <div class="pagebr">content1</div>
    <div class="pagebr">content2</div>
    <div class="pagebr">content3</div>
    <div class="pagebr">content4</div>
    <div class="pagebr">content5</div>
    <div class="pagebr">content6</div>
    <div class="pagebr">content7</div>
</div></code>```

Alternative way

If you want 3 divs inside a page then you could go with the following solution

To have a page braek in every 3 div you have to use selector :nth-child(3n) to give page-break-after: always;

div.pagebr:nth-child(3n) {
  page-break-after: always;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div>
  <div class="pagebr">content1</div>
  <div class="pagebr">content2</div>
  <div class="pagebr">content3</div>
  <div class="pagebr">content4</div>
  <div class="pagebr">content5</div>
  <div class="pagebr">content6</div>
  <div class="pagebr">content7</div>
</div></code>```

To know more about more details about page-break go through this and this links

Body:
My html is having this kind of structure :

content1

content2

content3

content4

content5

content6

content7

All the inner Div elements are coming dynamically. Sometimes there will be one or two div or may be all. It is not fixed. But total are 7.
When I write class -

div.pagebr
{
    page-break-after:always;
}

Every div move to next new page creating empty space after div element.
page-break-before:always; does the same and page-break-after:auto;  is not working anymore.

How should I add class for the Div elements, so that they can be fit on each page without breaking? Or is there any alternate solution?

Any help is appreciated.
Thanks.

Body:
Page content can not be fit in a page in case of dynamic elements. If you want avoid page break inside your div you can specify page-break-inside:avoid; like following example

div.pagebr
{
    page-break-inside:avoid;
}

<div>
    <div class="pagebr">content1</div>
    <div class="pagebr">content2</div>
    <div class="pagebr">content3</div>
    <div class="pagebr">content4</div>
    <div class="pagebr">content5</div>
    <div class="pagebr">content6</div>
    <div class="pagebr">content7</div>
</div>

Alternative way

If you want 3 divs inside a page then you could go with the following solution

To have a page braek in every 3 div you have to use selector :nth-child(3n) to give page-break-after: always;

div.pagebr:nth-child(3n) {
  page-break-after: always;
}

<div>
  <div class="pagebr">content1</div>
  <div class="pagebr">content2</div>
  <div class="pagebr">content3</div>
  <div class="pagebr">content4</div>
  <div class="pagebr">content5</div>
  <div class="pagebr">content6</div>
  <div class="pagebr">content7</div>
</div>

To know more about more details about page-break go through this and this links


问:
Horizontally Placed Equal Width Equal Horizontal Space Buttons With Auto Layout
I have written the following code to achieve

Horizontally spaced equal width fixed height equal horizontal spaced three button but somehow it's not working fine. Can anyone rectify this ?

```<code>UIButton *cancelBtn = [UIButton new];

cancelBtn.frame = CGRectMake(10, 5, (popupView.bounds.size.width-40)/3, 30);

[cancelBtn setTitle:@"Cancel" forState:UIControlStateNormal];

[cancelBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];

[cancelBtn setBackgroundColor:[UIColor lightGrayColor]];

[popupView addSubview:cancelBtn];

UIButton *resetBtn = [UIButton new];

resetBtn.frame = CGRectMake(cancelBtn.frame.origin.x+cancelBtn.bounds.size.width+10, 5, (popupView.bounds.size.width-40)/3, 30);

[resetBtn setTitle:@"Reset" forState:UIControlStateNormal];

[resetBtn setTitleColor:[UIColor yellowColor] forState:UIControlStateNormal];

[resetBtn setBackgroundColor:[UIColor darkGrayColor]];

[popupView addSubview:resetBtn];

UIButton *doneBtn = [UIButton new];

doneBtn.frame = CGRectMake(popupView.bounds.size.width-10-((popupView.bounds.size.width-40)/3), 5, (popupView.bounds.size.width-40)/3, 30);

[doneBtn setTitle:@"Done" forState:UIControlStateNormal];

[doneBtn setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];

[doneBtn setBackgroundColor:[UIColor blackColor]];

[popupView addSubview:doneBtn];

cancelBtn.translatesAutoresizingMaskIntoConstraints = NO;

[cancelBtn addConstraint:[NSLayoutConstraint constraintWithItem:cancelBtn attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1 constant:30]];

[popupView addConstraint:[NSLayoutConstraint constraintWithItem:cancelBtn attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:popupView attribute:NSLayoutAttributeTop multiplier:1.0f constant:5.0f] ];

[popupView addConstraint:[NSLayoutConstraint constraintWithItem:cancelBtn attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:popupView attribute:NSLayoutAttributeLeft multiplier:1.0f constant:10.0f]];
 resetBtn.translatesAutoresizingMaskIntoConstraints = NO;

[resetBtn addConstraint:[NSLayoutConstraint constraintWithItem:resetBtn attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1 constant:30]];

[popupView addConstraint:[NSLayoutConstraint constraintWithItem:resetBtn attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:popupView attribute:NSLayoutAttributeTop multiplier:1.0f constant:5.0f] ];

[popupView addConstraint:[NSLayoutConstraint constraintWithItem:cancelBtn attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:resetBtn attribute:NSLayoutAttributeLeft multiplier:1.0f constant:10.0f]];

[popupView addConstraint:[NSLayoutConstraint constraintWithItem:doneBtn attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:resetBtn attribute:NSLayoutAttributeRight multiplier:1.0f constant:-10.0f]];

doneBtn.translatesAutoresizingMaskIntoConstraints = NO;

[doneBtn addConstraint:[NSLayoutConstraint constraintWithItem:doneBtn attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1 constant:30]];

[popupView addConstraint:[NSLayoutConstraint constraintWithItem:doneBtn attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:popupView attribute:NSLayoutAttributeTop multiplier:1.0f constant:5.0f] ];

[popupView addConstraint:[NSLayoutConstraint constraintWithItem:doneBtn attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:popupView attribute:NSLayoutAttributeRight multiplier:1.0f constant:-10.0f]];
[popupView addConstraint:[NSLayoutConstraint     constraintWithItem:cancelBtn attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:resetBtn attribute:NSLayoutAttributeWidth multiplier:1 constant:0]];

[popupView addConstraint:[NSLayoutConstraint constraintWithItem:resetBtn attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:doneBtn attribute:NSLayoutAttributeWidth multiplier:1 constant:0]];
</code>```

How to fix this ?

I want to achieve a popup like this.

enter image description here

答:
Image 1

Image 2

They are appearing one over another.

Body:
I have written the following code to achieve

Horizontally spaced equal width fixed height equal horizontal spaced three button but somehow it's not working fine. Can anyone rectify this ?

UIButton *cancelBtn = [UIButton new];

cancelBtn.frame = CGRectMake(10, 5, (popupView.bounds.size.width-40)/3, 30);

[cancelBtn setTitle:@"Cancel" forState:UIControlStateNormal];

[cancelBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];

[cancelBtn setBackgroundColor:[UIColor lightGrayColor]];

[popupView addSubview:cancelBtn];

UIButton *resetBtn = [UIButton new];

resetBtn.frame = CGRectMake(cancelBtn.frame.origin.x+cancelBtn.bounds.size.width+10, 5, (popupView.bounds.size.width-40)/3, 30);

[resetBtn setTitle:@"Reset" forState:UIControlStateNormal];

[resetBtn setTitleColor:[UIColor yellowColor] forState:UIControlStateNormal];

[resetBtn setBackgroundColor:[UIColor darkGrayColor]];

[popupView addSubview:resetBtn];

UIButton *doneBtn = [UIButton new];

doneBtn.frame = CGRectMake(popupView.bounds.size.width-10-((popupView.bounds.size.width-40)/3), 5, (popupView.bounds.size.width-40)/3, 30);

[doneBtn setTitle:@"Done" forState:UIControlStateNormal];

[doneBtn setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];

[doneBtn setBackgroundColor:[UIColor blackColor]];

[popupView addSubview:doneBtn];

cancelBtn.translatesAutoresizingMaskIntoConstraints = NO;

[cancelBtn addConstraint:[NSLayoutConstraint constraintWithItem:cancelBtn attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1 constant:30]];

[popupView addConstraint:[NSLayoutConstraint constraintWithItem:cancelBtn attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:popupView attribute:NSLayoutAttributeTop multiplier:1.0f constant:5.0f] ];

[popupView addConstraint:[NSLayoutConstraint constraintWithItem:cancelBtn attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:popupView attribute:NSLayoutAttributeLeft multiplier:1.0f constant:10.0f]];
 resetBtn.translatesAutoresizingMaskIntoConstraints = NO;

[resetBtn addConstraint:[NSLayoutConstraint constraintWithItem:resetBtn attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1 constant:30]];

[popupView addConstraint:[NSLayoutConstraint constraintWithItem:resetBtn attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:popupView attribute:NSLayoutAttributeTop multiplier:1.0f constant:5.0f] ];

[popupView addConstraint:[NSLayoutConstraint constraintWithItem:cancelBtn attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:resetBtn attribute:NSLayoutAttributeLeft multiplier:1.0f constant:10.0f]];

[popupView addConstraint:[NSLayoutConstraint constraintWithItem:doneBtn attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:resetBtn attribute:NSLayoutAttributeRight multiplier:1.0f constant:-10.0f]];

doneBtn.translatesAutoresizingMaskIntoConstraints = NO;

[doneBtn addConstraint:[NSLayoutConstraint constraintWithItem:doneBtn attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1 constant:30]];

[popupView addConstraint:[NSLayoutConstraint constraintWithItem:doneBtn attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:popupView attribute:NSLayoutAttributeTop multiplier:1.0f constant:5.0f] ];

[popupView addConstraint:[NSLayoutConstraint constraintWithItem:doneBtn attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:popupView attribute:NSLayoutAttributeRight multiplier:1.0f constant:-10.0f]];
[popupView addConstraint:[NSLayoutConstraint     constraintWithItem:cancelBtn attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:resetBtn attribute:NSLayoutAttributeWidth multiplier:1 constant:0]];

[popupView addConstraint:[NSLayoutConstraint constraintWithItem:resetBtn attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:doneBtn attribute:NSLayoutAttributeWidth multiplier:1 constant:0]];

How to fix this ?

I want to achieve a popup like this.

enter image description here


问:
How to get decoded objectGUID from Active directory using UnboundID LDAP SDK in java?
Scenario 1: I am able to obtain objectGUID from active directory but it's not in readable string format. Also we need to store it in db with decoded format. With the given example in the provided link "http://www.developerscrappad.com/1109/windows/active-directory/java-ldap-jndi-2-ways-of-decoding-and-using-the-objectguid-from-windows-active-directory/", it demonstrates how to decode objectGUID, but they considered objectGUID length 16 byte(128 bit). In our case, when I try to obtain objectGUID, i get more than 128 bit and sometime i get less than 128 bit i.e we don't get specific bit length.
My implemented code for the reference:

```<code>public class GetLDAPUsers {

public static void main(String args[]) {
    new GetLDAPUsers().getUserFromAD();
}

void getUserFromAD() {
    try {
        LDAPConnection connection = new LDAPConnection("192.xxx.xx.xxx", 389);
        System.out.println(connection);
        String baseDN = "DC=wcomp1,DC=com";
        String[] attributes = { "entryUUID", "sn", "mail", "givenName",
                "objectGUID", "userAccountControl", "isDeleted", "modifyTimestamp", "WhenChanged", "WhenCreated"};
        // Set Ldap Connection Options for server timeout
        LDAPConnectionOptions connOption = new LDAPConnectionOptions();
        connOption.setAutoReconnect(true);
        connOption.setConnectTimeoutMillis(55000);
        connection.setConnectionOptions(connOption);
        //connection bind
        connection.bind("CN=abc,CN=ab,DC=users,DC=com", "password");
        System.out.println("connection successfully");

        //search filter query for search specific user,for all users use (&(objectclass=User)) filter.
        Filter filter = Filter.create("(&(objectclass=User)(givenName=testUserName))");
        SearchRequest searchRequest = new SearchRequest(baseDN, SearchScope.SUB, filter,
                attributes);
        SearchResult searchResult = connection.search(searchRequest);
        //get user detail
        for (SearchResultEntry searchResultEntry : searchResult.getSearchEntries()) {

            System.out.println("user name " + searchResultEntry.getAttribute("givenName").getValue() +
                    searchResultEntry.getAttribute("objectGUID").getValue()); //We get here objectGUID string which unreadable format

            //We convert here objectGUID in dashed string
            System.out.println("decoded objectGUID = " + convertToDashedString(searchResultEntry.getAttribute("objectGUID").getValue().getBytes()));
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static String convertToDashedString(byte[] objectGUID) {
    StringBuilder displayStr = new StringBuilder();
    displayStr.append(prefixZeros((int) objectGUID[3] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[2] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[1] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[0] & 0xFF));
    displayStr.append("-");
    displayStr.append(prefixZeros((int) objectGUID[5] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[4] & 0xFF));
    displayStr.append("-");
    displayStr.append(prefixZeros((int) objectGUID[7] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[6] & 0xFF));
    displayStr.append("-");
    displayStr.append(prefixZeros((int) objectGUID[8] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[9] & 0xFF));
    displayStr.append("-");
    displayStr.append(prefixZeros((int) objectGUID[10] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[11] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[12] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[13] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[14] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[15] & 0xFF));
    return displayStr.toString();
}

private static String prefixZeros(int value) {
    if (value <= 0xF) {
        StringBuilder sb = new StringBuilder("0");
        sb.append(Integer.toHexString(value));

        return sb.toString();

    } else {
        return Integer.toHexString(value);
    }
}
</code>```

}

Scenario 2: Also when i try to fetch objectGUID using above example in windows environment and linux environment I get different objectGUID for the same user.

答:
You cannot interpret the ObjectGUID as a string. Normally, I would set directory context environment to return ObjectGUID as a byte[] and then use the convert method

```<code>env.put("java.naming.ldap.attributes.binary", "ObjectGUID");

String newGuid = convertToDashedString(guid);
</code>```

Body:
Scenario 1: I am able to obtain objectGUID from active directory but it's not in readable string format. Also we need to store it in db with decoded format. With the given example in the provided link "http://www.developerscrappad.com/1109/windows/active-directory/java-ldap-jndi-2-ways-of-decoding-and-using-the-objectguid-from-windows-active-directory/", it demonstrates how to decode objectGUID, but they considered objectGUID length 16 byte(128 bit). In our case, when I try to obtain objectGUID, i get more than 128 bit and sometime i get less than 128 bit i.e we don't get specific bit length.
My implemented code for the reference:

public class GetLDAPUsers {

public static void main(String args[]) {
    new GetLDAPUsers().getUserFromAD();
}

void getUserFromAD() {
    try {
        LDAPConnection connection = new LDAPConnection("192.xxx.xx.xxx", 389);
        System.out.println(connection);
        String baseDN = "DC=wcomp1,DC=com";
        String[] attributes = { "entryUUID", "sn", "mail", "givenName",
                "objectGUID", "userAccountControl", "isDeleted", "modifyTimestamp", "WhenChanged", "WhenCreated"};
        // Set Ldap Connection Options for server timeout
        LDAPConnectionOptions connOption = new LDAPConnectionOptions();
        connOption.setAutoReconnect(true);
        connOption.setConnectTimeoutMillis(55000);
        connection.setConnectionOptions(connOption);
        //connection bind
        connection.bind("CN=abc,CN=ab,DC=users,DC=com", "password");
        System.out.println("connection successfully");

        //search filter query for search specific user,for all users use (&(objectclass=User)) filter.
        Filter filter = Filter.create("(&(objectclass=User)(givenName=testUserName))");
        SearchRequest searchRequest = new SearchRequest(baseDN, SearchScope.SUB, filter,
                attributes);
        SearchResult searchResult = connection.search(searchRequest);
        //get user detail
        for (SearchResultEntry searchResultEntry : searchResult.getSearchEntries()) {

            System.out.println("user name " + searchResultEntry.getAttribute("givenName").getValue() +
                    searchResultEntry.getAttribute("objectGUID").getValue()); //We get here objectGUID string which unreadable format

            //We convert here objectGUID in dashed string
            System.out.println("decoded objectGUID = " + convertToDashedString(searchResultEntry.getAttribute("objectGUID").getValue().getBytes()));
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static String convertToDashedString(byte[] objectGUID) {
    StringBuilder displayStr = new StringBuilder();
    displayStr.append(prefixZeros((int) objectGUID[3] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[2] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[1] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[0] & 0xFF));
    displayStr.append("-");
    displayStr.append(prefixZeros((int) objectGUID[5] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[4] & 0xFF));
    displayStr.append("-");
    displayStr.append(prefixZeros((int) objectGUID[7] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[6] & 0xFF));
    displayStr.append("-");
    displayStr.append(prefixZeros((int) objectGUID[8] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[9] & 0xFF));
    displayStr.append("-");
    displayStr.append(prefixZeros((int) objectGUID[10] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[11] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[12] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[13] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[14] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[15] & 0xFF));
    return displayStr.toString();
}

private static String prefixZeros(int value) {
    if (value <= 0xF) {
        StringBuilder sb = new StringBuilder("0");
        sb.append(Integer.toHexString(value));

        return sb.toString();

    } else {
        return Integer.toHexString(value);
    }
}

}

Scenario 2: Also when i try to fetch objectGUID using above example in windows environment and linux environment I get different objectGUID for the same user.

Body:
You cannot interpret the ObjectGUID as a string. Normally, I would set directory context environment to return ObjectGUID as a byte[] and then use the convert method

env.put("java.naming.ldap.attributes.binary", "ObjectGUID");

String newGuid = convertToDashedString(guid);


问:
Jumping Scrollbar after auto-expanding textarea
I have an auto-expanding textarea.  When pasting extremely long text (longer than window height), subsequent typing causes the browser scrollbar to jump.  This happens when trying to type at the bottom, because the document height is also growing.

Ideas, anyone?

Codepen:  https://codepen.io/btn-ninja/pen/bRVKYe

```<code>function growTextarea (i,elem) {
    var elem = $(elem);
    var offset = elem.prop('offsetHeight') - elem.prop('clientHeight');
     var resizeTextarea = function( elem ) {
        elem.css('height', 'auto').css('height', elem.prop('scrollHeight') + offset );
    };
    elem.on('input', function() {
        resizeTextarea( $(this) );
    });
    resizeTextarea( $(elem) );
}

$('.jTextarea').each(growTextarea);
</code>```

答:
This is better than my last attempt, even though I got the solution here :). This is basically storing the scroll position before the resize and then reapplying those values to the scroll position after the textarea is resized.

On an unrelated note. I have also removed the + offset on the height change jQuery, because it kept on adding unneeded additional height to the textarea. Doing this added a scroll bar on the textarea, so I set the textarea to overflow:hidden in the CSS.

https://codepen.io/anon/pen/QgjVWY

function growTextarea (i,elem) {
        var elem = $(elem);
        var offset = elem.prop('offsetHeight') - elem.prop('clientHeight');
        var resizeTextarea = function( elem ) {
          // two additional variables getting the top and left scoll positions.
          var scrollLeft = window.pageXOffset || (document.documentElement || document.body.parentNode || document.body).scrollLeft;
          var scrollTop  = window.pageYOffset || (document.documentElement || document.body.parentNode || document.body).scrollTop;
          elem.css('height', 'auto').css('height', elem.prop('scrollHeight') );
          // Applying previous top and left scroll position after textarea resize.
          window.scrollTo(scrollLeft, scrollTop);
        };
        elem.on('input', function() {
          resizeTextarea( $(this) );
        });
        resizeTextarea( $(elem) );
}

$('.jTextarea').each(growTextarea);```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.jTextarea {
  overflow:hidden;
}</code>```

<form style="width:500px; margin:20px auto;">
  Known issue: When pasting extremely long text (longer than window height), subsequent typing causes the browser scrollbar to jump.

  <textarea rows="1" class="jTextarea"></textarea>
</form>
```

Body:
I have an auto-expanding textarea.  When pasting extremely long text (longer than window height), subsequent typing causes the browser scrollbar to jump.  This happens when trying to type at the bottom, because the document height is also growing.

Ideas, anyone?

Codepen:  https://codepen.io/btn-ninja/pen/bRVKYe

function growTextarea (i,elem) {
    var elem = $(elem);
    var offset = elem.prop('offsetHeight') - elem.prop('clientHeight');
     var resizeTextarea = function( elem ) {
        elem.css('height', 'auto').css('height', elem.prop('scrollHeight') + offset );
    };
    elem.on('input', function() {
        resizeTextarea( $(this) );
    });
    resizeTextarea( $(elem) );
}

$('.jTextarea').each(growTextarea);

Body:
This is better than my last attempt, even though I got the solution here :). This is basically storing the scroll position before the resize and then reapplying those values to the scroll position after the textarea is resized.

On an unrelated note. I have also removed the + offset on the height change jQuery, because it kept on adding unneeded additional height to the textarea. Doing this added a scroll bar on the textarea, so I set the textarea to overflow:hidden in the CSS.

https://codepen.io/anon/pen/QgjVWY

function growTextarea (i,elem) {
        var elem = $(elem);
        var offset = elem.prop('offsetHeight') - elem.prop('clientHeight');
        var resizeTextarea = function( elem ) {
          // two additional variables getting the top and left scoll positions.
          var scrollLeft = window.pageXOffset || (document.documentElement || document.body.parentNode || document.body).scrollLeft;
          var scrollTop  = window.pageYOffset || (document.documentElement || document.body.parentNode || document.body).scrollTop;
          elem.css('height', 'auto').css('height', elem.prop('scrollHeight') );
          // Applying previous top and left scroll position after textarea resize.
          window.scrollTo(scrollLeft, scrollTop);
        };
        elem.on('input', function() {
          resizeTextarea( $(this) );
        });
        resizeTextarea( $(elem) );
}

$('.jTextarea').each(growTextarea);

.jTextarea {
  overflow:hidden;
}

<form style="width:500px; margin:20px auto;">
  <small>Known issue: When pasting extremely long text (longer than window height), subsequent typing causes the browser scrollbar to jump.</small><br>
  <textarea rows="1" class="jTextarea"></textarea>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>


问:
PHPMailer - send PHP generated PDF (mPDF) as attachment
I know how to generate PDF using mPDF library and send it as attachment using PHPMailer - something like this:

```<code>...
$emailAttachment = $mpdf->Output('file.pdf', 'S');
$mail = new PHPMailer();
$mail->AddStringAttachment($emailAttachment, 'file.pdf', 'base64', 'application/pdf');
...
</code>```

But what if I generate PDF in separate PHP file (that should not be modified) - like this - invoice.php:

```<code>...
$mpdf = new mPDF();
$mpdf->WriteHTML($html);
$mpdf->Output();
exit;
</code>```

How can I attach this dynamically created PDF file using PHPMailer?
I tried this:

```<code>$mail = new PHPMailer();
...
$mail->addStringAttachment(file_get_contents('invoice.php'), 'invoice.pdf',  'base64', 'application/pdf');
$mail->send();
</code>```

Email is sent with correct content but PDF attachment is corrupted and thus cannot be displayed. How to encode it correctly? I tried few other ways but file is corrupted or is not attached at all (in one case, whole email body was blank).

Thank you for your help in advance! :)

答:
The problem is that you're using file_get_contents incorrectly; as you've used it, it will fetch the contents of include.php, not the results of its execution. You need to expand it to a full URL in order to have it fetched that way, though I would advise not doing that. Have the script generate a PDF file and then load that, using the file output option of mpdf:

```<code>$mpdf = new mPDF();
$mpdf->WriteHTML($html);
$mpdf->Output('/path/to/files/invoice.pdf', 'F');
</code>```

Then run that script and attach the resulting file from PHPMailer (and delete the file afterwards):

```<code>include 'invoice.php';
$mail = new PHPMailer();
...
$mail->addAttachment('/path/to/files/doc.pdf');
$mail->send();
unlink('/path/to/files/invoice.pdf');
</code>```

You could skip the external file approach by using the "return a string" output mode (S) of the Output method and returning the string from the included file:

```<code>$mpdf = new mPDF();
$mpdf->WriteHTML($html);
return $mpdf->Output('invoice.pdf', 'S');
</code>```

and then:

```<code>$pdf = include 'invoice.php';
$mail = new PHPMailer();
...
$mail->addStringAttachment($pdf, 'invoice.pdf');
$mail->send();
</code>```

Body:
I know how to generate PDF using mPDF library and send it as attachment using PHPMailer - something like this:

...
$emailAttachment = $mpdf->Output('file.pdf', 'S');
$mail = new PHPMailer();
$mail->AddStringAttachment($emailAttachment, 'file.pdf', 'base64', 'application/pdf');
...

But what if I generate PDF in separate PHP file (that should not be modified) - like this - invoice.php:

...
$mpdf = new mPDF();
$mpdf->WriteHTML($html);
$mpdf->Output();
exit;

How can I attach this dynamically created PDF file using PHPMailer?
I tried this:

$mail = new PHPMailer();
...
$mail->addStringAttachment(file_get_contents('invoice.php'), 'invoice.pdf',  'base64', 'application/pdf');
$mail->send();

Email is sent with correct content but PDF attachment is corrupted and thus cannot be displayed. How to encode it correctly? I tried few other ways but file is corrupted or is not attached at all (in one case, whole email body was blank).

Thank you for your help in advance! :)

Body:
The problem is that you're using file_get_contents incorrectly; as you've used it, it will fetch the contents of include.php, not the results of its execution. You need to expand it to a full URL in order to have it fetched that way, though I would advise not doing that. Have the script generate a PDF file and then load that, using the file output option of mpdf:

$mpdf = new mPDF();
$mpdf->WriteHTML($html);
$mpdf->Output('/path/to/files/invoice.pdf', 'F');

Then run that script and attach the resulting file from PHPMailer (and delete the file afterwards):

include 'invoice.php';
$mail = new PHPMailer();
...
$mail->addAttachment('/path/to/files/doc.pdf');
$mail->send();
unlink('/path/to/files/invoice.pdf');

You could skip the external file approach by using the "return a string" output mode (S) of the Output method and returning the string from the included file:

$mpdf = new mPDF();
$mpdf->WriteHTML($html);
return $mpdf->Output('invoice.pdf', 'S');

and then:

$pdf = include 'invoice.php';
$mail = new PHPMailer();
...
$mail->addStringAttachment($pdf, 'invoice.pdf');
$mail->send();