jpype-project / jpype

JPype is cross language bridge to allow Python programs full access to Java class libraries.
http://www.jpype.org
Apache License 2.0
1.11k stars 179 forks source link

'jpype._jarray.byte[]' to utf-8 string #359

Closed EdLipson5117 closed 5 years ago

EdLipson5117 commented 5 years ago

I have what I think is a Unicode issue which I can't figure out. I'm getting back a TEXT/CLOB column from a datasource via a JDBC call using JayDeBeApi, which in turn used jpype (jpype1 0.6.2). It works fine for normal datatypes. I just can't seem to figure out how to process the data into a string I can use in a report. I was getting jpype._jarray._byte[] as the type. I looked in Python\Python35\Lib\site-packages\jpype_jarray.py and found the byteArrayStr function which made the byte[] a str.

I just don't see how to take it further and get a usable UTF-8 string. Is byte[] a bytearray? ba = str(tx,'UTF-8') which I found on StackExchange throws the error: TypeError: coercing to str: need a bytes-like object, byte[] found

If I use a Java program such as DBVisualizer, I see the data in that tool (I just copied the first 19 columns of the first few rows, have to protect confidentiality of company information)

T_MESSAGE [FIRCOSOFT X] [FIRCOSOFT X] [BUSINESS X] [APPLI X] [UNIT X] [TYPE X] [AMOUNT X] [REFERENCE X] [SERVICE X] [USERREF X] [VALUEDATE X] [MNE X] [DB X] [CR X] [ACCT X]

`


............................................

jdbc database call to get the column
............................................
def get_message_tx2(self):  
    """
    get the text data which is returned as a TEXT/CLOB in the JDBC call
    """
    qu = "SELECT T_MESSAGE FROM TABLE LIMIT TO 1 ROWS"
    csr = conn.cursor()
    try:
        csr.execute(qu)
    except Exception as e:
        logging.error(e)
        logging.error(qu)
        raise
    else:
        try:
            data = csr.fetchall()
        except Exception as e:
            logging.error(e)
            raise
        else:
            csr.close()
            return data
............................................
Code to look at the data, needed for a report
............................................
data = get_message_tx2()
import jpype
for tx1 in data:
    tx = tx1[0] # tx is a 'jpype._jarray.byte[]'
    bas = jpype._jarray._byteArrayStr(tx) # bas is now a str
    uni = bas.encode('UTF-8')
    logging.info(uni)
    `logging.info(uni.decode('UTF-8'))`

```............................................    
logging information from log
............................................    
2018-10-26 07:44:29,010 INFO b'\x10\x00\xc3\x96\xc3\xb0\x08\x00\x00\x00' 
2018-10-26 07:44:29,010 INFO  Öð    
Thrameos commented 5 years ago

Full support for unicode UTF-8 was not added until 0.7.0 (currently unreleased devel branch).

You should be able to do it manually in 0.6.2.

import jpype
import jpype.imports
jpype.startJVM(jpype.getDefaultJVMPath())
from java.lang import String

s= bytes('My String', 'UTF-8')  # Convert the python string into bytes
print(String(s, 'UTF-8'))            # Manually decode the string into java string 
EdLipson5117 commented 5 years ago

I added this code, to test the system before working it into my code. import jpype import jpype.imports jpype.startJVM(jpype.getDefaultJVMPath()) from java.lang import String

s= bytes('My String', 'UTF-8') print(String(s, 'UTF-8'))

When run in 3.5.4 with 0.6.2 jpype JayDeBeApi 1.1.1 jdcal 1.3 jira 1.0.10 jpype1 0.6.2 ldif3 3.2.2 macholib 1.9

JAVA connect exception cannot import name 'JClassUtil' error url jdbc:attconnect://r08jp10ha:2551/OSA;DefTdpName=OSAPRD_test;user=xeaa2ll;password=pw;CHARSET=UTF8 Traceback (most recent call last): File "OSA_Test.py", line 44, in import jpype File "c:\Users\xeaa2ll\AppData\Local\Programs\Python\Python35\lib\site-packages\jpype__init__.py", line 21, in from ._jproxy import * File "c:\Users\xeaa2ll\AppData\Local\Programs\Python\Python35\lib\site-packages\jpype_jproxy.py", line 23, in from . import JClassUtil ImportError: cannot import name 'JClassUtil'

It had originally failed on the import jpype.imports, and then I tried to upgrade jpype1 but that failed because no C++ environment and backed itself out.

Traceback (most recent call last): File "OSA_Test.py", line 45, in import jpype.imports ImportError: No module named 'jpype.imports'

C:\Users\XEAA2LL\Documents\code\ILMG\ODM\python\OSA>py5 -m pip install jpype --upgrade Collecting jpype Could not find a version that satisfies the requirement jpype (from versions: ) No matching distribution found for jpype

C:\Users\XEAA2LL\Documents\code\ILMG\ODM\python\OSA>py5 -m pip install jpype1 --upgrade .... building '_jpype' extension error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools

----------------------------------------

Rolling back uninstall of JPype1 Command "c:\Users\xeaa2ll\AppData\Local\Programs\Python\Python35\python.exe -u -c "import setuptools, tokenize;file='c:\Users\xeaa2ll\AppData\Local\Temp\pip-install-e31rrtkk\jpype1\setup.py';f=getattr(tokenize, 'open', open)(file);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, file, 'exec'))" install --record c:\Users\xeaa2ll\AppData\Local\Temp\pip-record-xl3zn_yj\install-record.txt --single-version-externally-managed --compile" failed with error code 1 in c:\Users\xeaa2ll\AppData\Local\Temp\pip-install-e31rrtkk\jpype1\

Is there another mode to upgrade and would an upgrade help?

Thrameos commented 5 years ago

Imports only works for packages with a tld (java, com, gov, org). If you need to import something without a tld use JClass.

from . import JClassUtil =>

JClassUtil = JClass(‘JClassUtil”)