Repository: Cog-Creators/Red-DiscordBot

Issue:
(V3) Audio cog doesnt load
# Other bugs

<!-- 
Did you find a bug with something other than a command? Fill out the following:
-->

#### What were you trying to do?

I was normally, like everyone does, trying to load audio cog.

#### What were you expecting to happen?

I was expecting it to load normally and to be usable.

#### What actually happened?

It failed to load, throwing in the terminal this:

```py
[20/08/2018 02:50] ERROR core_commands _load 89: Package loading failed
Traceback (most recent call last):
  File "/home/ruben/.local/lib/python3.6/site-packages/redbot/core/core_commands.py", line 87, in _load
    await bot.load_extension(spec)
  File "/home/ruben/.local/lib/python3.6/site-packages/redbot/core/bot.py", line 226, in load_extension
    await lib.setup(self)
  File "/home/ruben/Downloads/Red-DiscordBot-3-develop/redbot/cogs/audio/__init__.py", line 53, in setup
    await start_lavalink_server(bot.loop)
  File "/home/ruben/Downloads/Red-DiscordBot-3-develop/redbot/cogs/audio/manager.py", line 68, in start_lavalink_server
    java_available, java_version = await has_java(loop)
  File "/home/ruben/Downloads/Red-DiscordBot-3-develop/redbot/cogs/audio/manager.py", line 47, in has_java
    version = await get_java_version(loop)
  File "/home/ruben/Downloads/Red-DiscordBot-3-develop/redbot/cogs/audio/manager.py", line 63, in get_java_version
    major, minor = version_string.split(".")[:2]
ValueError: not enough values to unpack (expected 2, got 1)
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7f8b24284ef0>
```

#### How can we reproduce this issue?

Im not sure, as i only installed like in the guide on arch linux, and it failed to load the cog right after the 1st startup, and i had java installed 
Version below v
[ruben@arch redbot]$ java -showversion
Picked up _JAVA_OPTIONS: 
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)

Edit: I was using python 3.6.6 from the aur, as the python that was in the repos was already python 3.7




Discussion:
@TheFallenAngel2001 Hi, thanks for reporting this issue. Could you please provide the output of `pip freeze`?
[ruben@arch redbot]$ pip freeze
appdirs==1.4.3
async-timeout==3.0.0
attrs==18.1.0
btrfsutil==1.0.0
CacheControl==0.12.5
chardet==3.0.4
colorama==0.3.9
discord.py==1.0.0a0
distlib==0.2.7
distro==1.3.0
evdev==1.0.0
fuzzywuzzy==0.16.0
html5lib==1.0.1
idna==2.7
idna-ssl==1.1.0
isc==2.0
lockfile==0.12.2
lutris==0.4.18.1
msgpack==0.5.6
multidict==4.3.1
numpy==1.15.0
packaging==17.1
progress==1.4
pycairo==1.17.0
pygobject==3.28.3
pyparsing==2.2.0
python-Levenshtein==0.12.0
python-libtorrent==1.1.9
pytoml==0.1.16
PyYAML==3.13
raven==6.9.0
raven-aiohttp==0.7.0
Red-Lavalink==0.1.1
Red-Trivia==1.1.1
requests==2.19.1
retrying==1.3.3
scapy===git-archive.devae348f861
six==1.11.0
team==1.0
urllib3==1.23
webencodings==0.5.1
websockets==6.0
yarl==1.2.6
youtube-dl==2018.8.4

[ruben@arch redbot]$ python3.6 -m pip freeze
aiohttp==3.3.2
aiohttp-json-rpc==0.11
appdirs==1.4.3
async-timeout==3.0.0
attrs==18.1.0
chardet==3.0.4
colorama==0.3.9
discord.py==1.0.0a0
distro==1.3.0
fuzzywuzzy==0.16.0
idna==2.7
idna-ssl==1.1.0
multidict==4.3.1
python-Levenshtein==0.12.0
PyYAML==3.13
raven==6.9.0
raven-aiohttp==0.7.0
Red-DiscordBot==3.0.0b19
Red-Lavalink==0.1.1
Red-Trivia==1.1.1
websockets==6.0
yarl==1.2.6

Sry wrong command, that one was from python 3.7

That's all good, thanks for the quick reply. I think I can see the issue, it's to do with how we're expecting `java -version` to display, that first line `Picked up by _JAVA_OPTIONS:` is unexpected. I'll try open a PR today to fix this.

Resolving patch:
diff --git a/redbot/cogs/audio/manager.py b/redbot/cogs/audio/manager.py
--- a/redbot/cogs/audio/manager.py
+++ b/redbot/cogs/audio/manager.py
@@ -1,9 +1,11 @@
 import shlex
 import shutil
 import asyncio
-from subprocess import Popen, DEVNULL, PIPE
+import asyncio.subprocess
 import os
 import logging
+import re
+from subprocess import Popen, DEVNULL
 from typing import Optional, Tuple
 
 _JavaVersion = Tuple[int, int]
@@ -45,23 +47,42 @@ async def has_java(loop) -> Tuple[bool, Optional[_JavaVersion]]:
         return False, None
 
     version = await get_java_version(loop)
-    return version >= (1, 8), version
+    return (2, 0) > version >= (1, 8) or version >= (8, 0), version
 
 
 async def get_java_version(loop) -> _JavaVersion:
     """
     This assumes we've already checked that java exists.
     """
-    proc = Popen(shlex.split("java -version", posix=os.name == "posix"), stdout=PIPE, stderr=PIPE)
-    _, err = proc.communicate()
-
-    version_info = str(err, encoding="utf-8")
-
-    version_line = version_info.split("\n")[0]
-    version_start = version_line.find('"')
-    version_string = version_line[version_start + 1 : -1]
-    major, minor = version_string.split(".")[:2]
-    return int(major), int(minor)
+    _proc: asyncio.subprocess.Process = await asyncio.create_subprocess_exec(
+        "java",
+        "-version",
+        stdout=asyncio.subprocess.PIPE,
+        stderr=asyncio.subprocess.PIPE,
+        loop=loop,
+    )
+    # java -version outputs to stderr
+    _, err = await _proc.communicate()
+
+    version_info: str = err.decode("utf-8")
+    # We expect the output to look something like:
+    #     $ java -version
+    #     ...
+    #     ... version "MAJOR.MINOR.PATCH[_BUILD]" ...
+    #     ...
+    # We only care about the major and minor parts though.
+    version_line_re = re.compile(r'version "(?P<major>\d+).(?P<minor>\d+).\d+(?:_\d+)?"')
+
+    lines = version_info.splitlines()
+    for line in lines:
+        match = version_line_re.search(line)
+        if match:
+            return int(match["major"]), int(match["minor"])
+
+    raise RuntimeError(
+        "The output of `java -version` was unexpected. Please report this issue on Red's "
+        "issue tracker."
+    )
 
 
 async def start_lavalink_server(loop):


Test patch: