Repository: chezou/tabula-py

Issue:
Getting 'OSError: [WinError 6] The handle is invalid' when i host tabula in IIS
# Check list before submit

Write and check the following questionaries.

- [ ] Did you read [FAQ](https://tabula-py.readthedocs.io/en/latest/faq.html)?
YES
- [ ] (Optional, but really helpful) Your PDF URL: ?

- [ ] Paste the output of `import tabula; tabula.environment_info()` on Python REPL: ?

>>> import tabula
>>> tabula.environment_info()
Python version:
    3.7.4 (tags/v3.7.4:e09359112e, Jul  8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)]
Java version:
    java version "1.8.0_231"
Java(TM) SE Runtime Environment (build 1.8.0_231-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.231-b11, mixed mode)
tabula-py version: 1.4.1
platform: Windows-8.1-6.3.9600-SP0
>>>
If not possible to execute `tabula.environment_info()`, please answer following questions manually.

- [ ] Paste the output of `python --version` command on your terminal: ?
- [ ] Paste the output of `java -version` command on your terminal: ?
- [ ] Does `java -h` command work well?; Ensure your java command is included in `PATH`
- [ ] Write your OS and it's version: ?


# What did you do when you faced the problem?

I am publishing my python code using Visual Studio 2019
It is running well in local when i access the local url
but when i run it using hosted url in IIS it shows following error

## Expected behavior:
Should run on IIS

## Actual behavior:
Code running fine in Local but not in IIS
```

File "C:\Program Files (x86)\Python37\lib\site-packages\tabula\wrapper.py", line 147, in read_pdf
    output = _run(java_options, kwargs, path, encoding)
  File "C:\Program Files (x86)\Python37\lib\site-packages\tabula\wrapper.py", line 67, in _run
    return subprocess.check_output(args)
  File "C:\Program Files (x86)\Python37\lib\subprocess.py", line 395, in check_output
    **kwargs).stdout
  File "C:\Program Files (x86)\Python37\lib\subprocess.py", line 472, in run
    with Popen(*popenargs, **kwargs) as process:
  File "C:\Program Files (x86)\Python37\lib\subprocess.py", line 728, in __init__
    errread, errwrite) = self._get_handles(stdin, stdout, stderr)
  File "C:\Program Files (x86)\Python37\lib\subprocess.py", line 1061, in _get_handles
    errwrite = _winapi.GetStdHandle(_winapi.STD_ERROR_HANDLE)
OSError: [WinError 6] The handle is invalid

```

Discussion:

Patch:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..4b95b89
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,23 @@
+# See https://pre-commit.com for more information
+# See https://pre-commit.com/hooks.html for more hooks
+repos:
+  - repo: https://github.com/pre-commit/pre-commit-hooks
+    rev: v2.0.0
+    hooks:
+    - id: trailing-whitespace
+    - id: end-of-file-fixer
+    - id: check-yaml
+    - id: check-added-large-files
+  - repo: https://github.com/asottile/seed-isort-config
+    rev: v1.9.3
+    hooks:
+    - id: seed-isort-config
+  - repo: https://github.com/pre-commit/mirrors-isort
+    rev: v4.3.21
+    hooks:
+    - id: isort
+  - repo: https://github.com/python/black
+    rev: stable
+    hooks:
+    - id: black
+      language_version: python3.8
diff --git a/.travis.yml b/.travis.yml
index dfed399..269f880 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,6 +4,7 @@ language: python
 python:
 - 3.6
 - 3.7
+- 3.8
 before_install:
 - pip install --upgrade setuptools
 install:
diff --git a/setup.cfg b/setup.cfg
index 50f2553..ae94dd5 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -59,4 +59,4 @@ exclude =
 line_length = 88
 multi_line_output = 3
 include_trailing_comma = True
-known_third_party = pandas,numpy,distro
+known_third_party = nox,numpy,pandas,pkg_resources,setuptools,sphinx_rtd_theme
diff --git a/tabula/wrapper.py b/tabula/wrapper.py
index 81d4de2..fdf7b20 100644
--- a/tabula/wrapper.py
+++ b/tabula/wrapper.py
@@ -77,7 +77,16 @@ def _run(java_options, options, path=None, encoding="utf-8"):
         args.append(path)
 
     try:
-        return subprocess.check_output(args)
+        result = subprocess.run(
+            args,
+            stdout=subprocess.PIPE,
+            stderr=subprocess.PIPE,
+            stdin=subprocess.DEVNULL,
+            check=True,
+        )
+        if result.stderr:
+            logger.warning("Got stderr: {}".format(result.stderr.decode(encoding)))
+        return result.stdout
     except FileNotFoundError:
         raise JavaNotFoundError(JAVA_NOT_FOUND_ERROR)
     except subprocess.CalledProcessError as e:


Test patch:
diff --git a/tests/test_read_pdf_table.py b/tests/test_read_pdf_table.py
index 32e4063..40773e5 100644
--- a/tests/test_read_pdf_table.py
+++ b/tests/test_read_pdf_table.py
@@ -3,6 +3,7 @@ import json
 import os
 import platform
 import shutil
+import subprocess
 import tempfile
 import unittest
 from unittest.mock import patch
@@ -229,7 +230,7 @@ class TestReadPdfTable(unittest.TestCase):
         self.assertEqual(len(dfs), 4)
         self.assertTrue(dfs[0].equals(pd.read_csv(self.expected_csv1)))
 
-    @patch("subprocess.check_output")
+    @patch("subprocess.run")
     @patch("tabula.wrapper._jar_path")
     def test_read_pdf_with_jar_path(self, jar_func, mock_fun):
         jar_func.return_value = "/tmp/tabula-java.jar"
@@ -248,7 +249,13 @@ class TestReadPdfTable(unittest.TestCase):
             "--guess",
             "tests/resources/data.pdf",
         ]
-        mock_fun.assert_called_with(target_args)
+        subp_args = {
+            "stdout": subprocess.PIPE,
+            "stderr": subprocess.PIPE,
+            "stdin": subprocess.DEVNULL,
+            "check": True,
+        }
+        mock_fun.assert_called_with(target_args, **subp_args)
 
 
 if __name__ == "__main__":