├── .github
└── workflows
│ ├── create.yml
│ ├── no-response.yml
│ ├── push-x86.yml
│ ├── push.yml
│ └── support.yml
├── .gitignore
├── .readthedocs.yaml
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTACT.md
├── CONTRIBUTING.md
├── FAQ.md
├── LICENSE
├── MANIFEST.in
├── Makefile
├── README.md
├── build.xml
├── docs
├── Makefile
├── make.bat
├── requirements.txt
└── source
│ ├── android.rst
│ ├── api.rst
│ ├── building.rst
│ ├── conf.py
│ ├── contact.rst
│ ├── contribute.rst
│ ├── faq.rst
│ ├── index.rst
│ ├── installation.rst
│ ├── packaging.rst
│ └── quickstart.rst
├── examples
└── arraylists
│ ├── arraylist.java
│ └── arraylist.py
├── jnius
├── __init__.py
├── env.py
├── jni.pxi
├── jnius.pyx
├── jnius_compat.pxi
├── jnius_conversion.pxi
├── jnius_env.pxi
├── jnius_export_class.pxi
├── jnius_export_func.pxi
├── jnius_jvm_android.pxi
├── jnius_jvm_desktop.pxi
├── jnius_jvm_dlopen.pxi
├── jnius_localref.pxi
├── jnius_nativetypes3.pxi
├── jnius_proxy.pxi
├── jnius_utils.pxi
├── reflect.py
├── signatures.py
└── src
│ └── org
│ └── jnius
│ └── NativeInvocationHandler.java
├── jnius_config.py
├── main.workflow
├── pyproject.toml
├── renovate.json
├── setup.cfg
├── setup.py
├── setup_sdist.py
└── tests
├── android
└── testhardware
│ └── main.py
├── java-src
└── org
│ ├── jnius
│ ├── BasicsTest.java
│ ├── CharsAndStrings.java
│ ├── Child.java
│ ├── ChildVisibilityTest.java
│ ├── ClassArgument.java
│ ├── CloseableClass.java
│ ├── ConstructorTest.java
│ ├── HelloWorld.java
│ ├── InterfaceWithPublicEnum.java
│ ├── MultipleDimensions.java
│ ├── MultipleMethods.java
│ ├── ObjectArgument.java
│ ├── Parent.java
│ ├── SimpleEnum.java
│ ├── VariableArgConstructors.java
│ ├── VariablePassing.java
│ └── VisibilityTest.java
│ └── jnius2
│ └── ChildVisibilityTest.java
├── test_arraylist.py
├── test_assignable.py
├── test_bad_declaration.py
├── test_basics.py
├── test_bytearray.py
├── test_cast.py
├── test_chars_and_strings.py
├── test_class_argument.py
├── test_closeable.py
├── test_collections.py
├── test_comparable.py
├── test_constructor.py
├── test_dir.py
├── test_enum.py
├── test_export_class.py
├── test_implementation.py
├── test_inheritance.py
├── test_int_vs_long.py
├── test_interface.py
├── test_jnitable_overflow.py
├── test_jnius_config.py
├── test_jvm_options.py
├── test_lambdas.py
├── test_method_multiple_signatures.py
├── test_multidimension.py
├── test_object_args.py
├── test_output_args.py
├── test_pass_by_reference_or_value.py
├── test_proxy.py
├── test_reflect.py
├── test_signature.py
├── test_simple.py
├── test_static.py
├── test_visibility_all.py
├── test_visibility_package_protected.py
├── test_visibility_public_only.py
└── test_visibility_public_protected.py
/.github/workflows/no-response.yml:
--------------------------------------------------------------------------------
1 | name: No Response
2 |
3 | # Both `issue_comment` and `scheduled` event types are required for this Action
4 | # to work properly.
5 | on:
6 | issue_comment:
7 | types: [created]
8 | schedule:
9 | # Schedule for an arbitrary time (4am) once every day
10 | - cron: '* 4 * * *'
11 |
12 | jobs:
13 | noResponse:
14 | runs-on: ubuntu-latest
15 | steps:
16 | - uses: lee-dohm/no-response@9bb0a4b5e6a45046f00353d5de7d90fb8bd773bb
17 | # This commit hash targets release v0.5.0 of lee-dohm/no-response.
18 | # Targeting a commit hash instead of a tag has been done for security reasons.
19 | # Please be aware that the commit hash specifically targets the "Automatic compilation"
20 | # done by `github-actions[bot]` as the `no-response` Action needs to be compiled.
21 | with:
22 | token: ${{ github.token }}
23 | daysUntilClose: 42
24 | responseRequiredLabel: 'awaiting-reply'
25 | closeComment: >
26 | This issue has been automatically closed because there has been no response
27 | to our request for more information from the original author. With only the
28 | information that is currently in the issue, we don't have the means
29 | to take action. Please reach out if you have or find the answers we need so
30 | that we can investigate further.
31 |
--------------------------------------------------------------------------------
/.github/workflows/push-x86.yml:
--------------------------------------------------------------------------------
1 | on: [push, pull_request]
2 | name: Continuous Integration (x86)
3 | jobs:
4 | Tests:
5 | name: base
6 | runs-on: ubuntu-latest
7 | strategy:
8 | matrix:
9 | python:
10 | - '3.8'
11 | - '3.9'
12 | - '3.10'
13 | - '3.11'
14 | container:
15 | image: i386/python:${{ matrix.python }}-buster
16 | steps:
17 | - name: info
18 | run: |
19 | linux32 sh -ec '
20 | cat /etc/*release || true
21 | uname -a
22 | git version
23 | python --version
24 | '
25 |
26 | - name: checkout
27 | run: |
28 | linux32 sh -ec '
29 | git config --global --add safe.directory '*'
30 | git init .
31 | git remote add origin https://github.com/$GITHUB_REPOSITORY
32 | git config --local gc.auto 0
33 | git fetch --no-tags --prune --progress --no-recurse-submodules \
34 | --depth=1 origin +$GITHUB_SHA:refs/remotes/origin/${GITHUB_REF##*/}
35 | git checkout --progress --force -B ${GITHUB_REF##*/} \
36 | refs/remotes/origin/${GITHUB_REF##*/}
37 | git log -1 --format=%H
38 | '
39 |
40 | - name: setup java
41 | run: |
42 | linux32 sh -ec '
43 | apt update
44 | apt install -y openjdk-11-jdk-headless ant
45 | java -version
46 | '
47 | env:
48 | DEBIAN_FRONTEND: noninteractive
49 |
50 | - name: install
51 | run: |
52 | linux32 sh -ec '
53 | pip install --timeout=120 .[dev,ci]
54 | '
55 |
56 | - name: test
57 | run: |
58 | linux32 sh -ec '
59 | ant all
60 | cd tests
61 | CLASSPATH=../build/test-classes:../build/classes pytest -v
62 | '
63 |
--------------------------------------------------------------------------------
/.github/workflows/push.yml:
--------------------------------------------------------------------------------
1 | on: [push, pull_request]
2 | name: Continuous Integration
3 | jobs:
4 | Tests:
5 | name: base
6 | continue-on-error: true
7 | strategy:
8 | matrix:
9 | python:
10 | - '3.8'
11 | - '3.9'
12 | - '3.10'
13 | - '3.11'
14 | - '3.12'
15 | - 'pypy-3.8'
16 | - 'pypy-3.9'
17 | java:
18 | - '8'
19 | - '11'
20 | - '23'
21 | os:
22 | # macos-latest (ATM macos-14) runs on Apple Silicon,
23 | # macos-13 runs on Intel
24 | - 'ubuntu-latest'
25 | - 'windows-latest'
26 | - 'macos-latest'
27 | - 'macos-13'
28 | cython:
29 | - '<3'
30 | - '>=3'
31 | architecture:
32 | - 'x64'
33 | - 'x86'
34 | - 'aarch64'
35 | exclude:
36 | - os: windows-latest
37 | architecture: aarch64
38 | - os: ubuntu-latest
39 | architecture: aarch64
40 | - os: ubuntu-latest
41 | architecture: x86
42 | - os: macos-13
43 | architecture: aarch64
44 | - os: macos-13
45 | architecture: x86
46 | - os: macos-latest
47 | architecture: aarch64
48 | java: '8'
49 | - os: macos-latest
50 | architecture: x64
51 | - os: macos-latest
52 | architecture: x86
53 | - os: windows-latest
54 | architecture: x86
55 | python: 'pypy-3.8'
56 | - os: windows-latest
57 | architecture: x86
58 | python: 'pypy-3.9'
59 | - os: windows-latest
60 | architecture: x86
61 | java: '20'
62 | - os: windows-latest
63 | architecture: x86
64 | java: '21'
65 | - os: windows-latest
66 | architecture: x86
67 | java: '22'
68 | - os: windows-latest
69 | architecture: x86
70 | java: '23'
71 |
72 | runs-on: ${{ matrix.os }}
73 | steps:
74 | - uses: actions/checkout@master
75 |
76 | - name: Setup python
77 | uses: actions/setup-python@v5
78 | with:
79 | python-version: ${{ matrix.python }}
80 | architecture: ${{ matrix.architecture == 'aarch64' && 'arm64' || matrix.architecture }}
81 |
82 | - name: Setup java
83 | uses: actions/setup-java@v4
84 | with:
85 | java-version: ${{ matrix.java }}
86 | distribution: 'temurin'
87 | architecture: ${{ matrix.architecture }}
88 |
89 | - name: (macOS) Setup test dependencies
90 | if: matrix.os == 'macos-latest' || matrix.os == 'macos-13'
91 | run: brew install ant
92 |
93 | - name: Build test classes via ant
94 | run: ant all
95 |
96 | - name: (Windows) Force Cython version
97 | # Windows sed doesnt accept .bak filename extensions
98 | if: matrix.os == 'windows-latest'
99 | run: sed -i 's/"Cython"/"Cython${{matrix.cython}}"/' pyproject.toml
100 |
101 | - name: (Linux, macOS) Force Cython version
102 | # macOS sed requires .bak filename extensions
103 | if: (matrix.os == 'ubuntu-latest') || (matrix.os == 'macos-latest') || (matrix.os == 'macos-13')
104 | run: sed -i.bak 's/"Cython"/"Cython${{matrix.cython}}"/' pyproject.toml
105 |
106 | - name: Install pyjnius with [dev, ci] extras
107 | run: |
108 | pip install --timeout=120 .[dev,ci]
109 |
110 | - name: (Windows) Test pyjnius via pytest
111 | if: matrix.os == 'windows-latest'
112 | run: |
113 | $env:PATH +=";$env:JAVA_HOME\jre\bin\server\;$env:JAVA_HOME\jre\bin\client\;$env:JAVA_HOME\bin\server\"
114 | $env:CLASSPATH ="../build/test-classes;../build/classes"
115 | cd tests
116 | pytest -v
117 |
118 | - name: (Linux, macOS) Test pyjnius via pytest
119 | if: (matrix.os == 'ubuntu-latest') || (matrix.os == 'macos-latest') || (matrix.os == 'macos-13')
120 | run: |
121 | cd tests
122 | CLASSPATH=../build/test-classes:../build/classes python -m pytest -v
123 |
124 | # - name: coveralls
125 | # run: python -m coveralls
126 | # env:
127 | # COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
128 |
--------------------------------------------------------------------------------
/.github/workflows/support.yml:
--------------------------------------------------------------------------------
1 | name: 'Support Requests'
2 |
3 | on:
4 | issues:
5 | types: [labeled, unlabeled, reopened]
6 |
7 | permissions:
8 | issues: write
9 |
10 | jobs:
11 | action:
12 | runs-on: ubuntu-latest
13 | steps:
14 | - uses: dessant/support-requests@v4
15 | with:
16 | github-token: ${{ github.token }}
17 | support-label: 'support'
18 | issue-comment: >
19 | 👋 We use the issue tracker exclusively for bug reports and feature requests.
20 | However, this issue appears to be a support request. Please use our
21 | [support channels](https://github.com/kivy/pyjnius/blob/master/CONTACT.md)
22 | to get help with the project.
23 |
24 | Let us know if this comment was made in error, and we'll be happy
25 | to reopen the issue.
26 | close-issue: true
27 | lock-issue: false
28 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyo
2 | *.pyc
3 | jnius/jnius.c
4 | jnius/config.pxi
5 | jnius/jnius.so
6 | build
7 | .*.swp
8 | *.class
9 | .idea
10 | *~
11 | *.so
12 | *.iml
13 | dist
14 | pyjnius.egg-info
15 | jnius.egg-info
16 | *.pyd
17 |
--------------------------------------------------------------------------------
/.readthedocs.yaml:
--------------------------------------------------------------------------------
1 | # Read the Docs configuration file for Sphinx projects
2 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
3 |
4 | version: 2
5 |
6 | build:
7 | os: ubuntu-22.04
8 | tools:
9 | python: "3"
10 |
11 | python:
12 | install:
13 | - requirements: docs/requirements.txt
14 |
15 | sphinx:
16 | configuration: docs/source/conf.py
17 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | In the interest of fostering an open and welcoming community, we as
2 | contributors and maintainers need to ensure participation in our project and
3 | our sister projects is a harassment-free and positive experience for everyone.
4 | It is vital that all interaction is conducted in a manner conveying respect,
5 | open-mindedness and gratitude.
6 |
7 | Please consult the [latest Kivy Code of Conduct](https://github.com/kivy/kivy/blob/master/CODE_OF_CONDUCT.md).
8 |
9 |
--------------------------------------------------------------------------------
/CONTACT.md:
--------------------------------------------------------------------------------
1 | # Contacting the Kivy Team
2 |
3 | If you are looking to contact the Kivy Team (who are responsible for managing
4 | the PyJNIus project), including looking for support, please see our
5 | latest [Contact Us](https://github.com/kivy/kivy/blob/master/CONTACT.md)
6 | document.
7 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contribution Guidelines
2 |
3 | PyJNIus is part of the [Kivy](https://kivy.org) ecosystem - a large group of
4 | products used by many thousands of developers for free, but it
5 | is built entirely by the contributions of volunteers. We welcome (and rely on)
6 | users who want to give back to the community by contributing to the project.
7 |
8 | Contributions can come in many forms. See the latest
9 | [Contribution Guidelines](https://github.com/kivy/kivy/blob/master/CONTRIBUTING.md)
10 | for how you can help us.
11 |
--------------------------------------------------------------------------------
/FAQ.md:
--------------------------------------------------------------------------------
1 | # FAQ for PyJNIus
2 |
3 | ## Introduction
4 |
5 | PyJNIus is a [Python](https://www.python.org/) library for accessing
6 | [Java](https://www.java.com/) classes using the
7 | [Java Native Interface](https://docs.oracle.com/javase/8/docs/technotes/guides/jni/)
8 | (JNI).
9 |
10 | Warning: the [PyPI](https://pypi.org/) package name is now
11 | [pyjnius](https://pypi.org/project/pyjnius/) instead of `jnius`.
12 |
13 | ## No questions yet
14 |
15 | No Frequently Asked Questions have been identified yet. Please contribute some.
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2010-2023 Kivy Team and other contributors
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include *LICENSE
2 | recursive-include jnius *.pyx *.pxi
3 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | all: build_ext
2 |
3 | .PHONY: build_ext tests
4 |
5 | PYTHON=python
6 | PYTEST=pytest
7 |
8 | JAVA_TARGET ?= $(shell $(PYTHON) -c "import re; print('1.6' if int(re.findall(r'\d+', '$(shell javac -version 2>&1)')[0]) < 12 else '1.7')" )
9 | JAVAC_OPTS=-target $(JAVA_TARGET) -source $(JAVA_TARGET)
10 | JAVAC=javac $(JAVAC_OPTS)
11 |
12 | ANT=ant -Dant.build.javac.source=$(JAVA_TARGET) -Dant.build.javac.target=$(JAVA_TARGET)
13 |
14 | build_ext:
15 | $(ANT) all
16 | $(PYTHON) setup.py build_ext --inplace -g
17 |
18 | clean:
19 | $(ANT) clean
20 | rm -rf build jnius/config.pxi
21 |
22 | html:
23 | $(MAKE) -C docs html
24 |
25 | # for use in travis; tests whatever you got.
26 | # use PYTHON3=1 to force python3 in other environments.
27 | tests:
28 | (cd tests; env CLASSPATH=../build/test-classes:../build/classes PYTHONPATH=..:$(PYTHONPATH) $(PYTEST) -v)
29 |
--------------------------------------------------------------------------------
/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
15 |
16 |
17 |
18 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = sphinx-build
7 | PAPER =
8 | BUILDDIR = build
9 |
10 | # Internal variables.
11 | PAPEROPT_a4 = -D latex_paper_size=a4
12 | PAPEROPT_letter = -D latex_paper_size=letter
13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
14 | # the i18n builder cannot share the environment and doctrees with the others
15 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
16 |
17 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
18 |
19 | help:
20 | @echo "Please use \`make ' where is one of"
21 | @echo " html to make standalone HTML files"
22 | @echo " dirhtml to make HTML files named index.html in directories"
23 | @echo " singlehtml to make a single large HTML file"
24 | @echo " pickle to make pickle files"
25 | @echo " json to make JSON files"
26 | @echo " htmlhelp to make HTML files and a HTML help project"
27 | @echo " qthelp to make HTML files and a qthelp project"
28 | @echo " devhelp to make HTML files and a Devhelp project"
29 | @echo " epub to make an epub"
30 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
31 | @echo " latexpdf to make LaTeX files and run them through pdflatex"
32 | @echo " text to make text files"
33 | @echo " man to make manual pages"
34 | @echo " texinfo to make Texinfo files"
35 | @echo " info to make Texinfo files and run them through makeinfo"
36 | @echo " gettext to make PO message catalogs"
37 | @echo " changes to make an overview of all changed/added/deprecated items"
38 | @echo " linkcheck to check all external links for integrity"
39 | @echo " doctest to run all doctests embedded in the documentation (if enabled)"
40 |
41 | clean:
42 | -rm -rf $(BUILDDIR)/*
43 |
44 | html:
45 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
46 | @echo
47 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
48 |
49 | dirhtml:
50 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
51 | @echo
52 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
53 |
54 | singlehtml:
55 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
56 | @echo
57 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
58 |
59 | pickle:
60 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
61 | @echo
62 | @echo "Build finished; now you can process the pickle files."
63 |
64 | json:
65 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
66 | @echo
67 | @echo "Build finished; now you can process the JSON files."
68 |
69 | htmlhelp:
70 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
71 | @echo
72 | @echo "Build finished; now you can run HTML Help Workshop with the" \
73 | ".hhp project file in $(BUILDDIR)/htmlhelp."
74 |
75 | qthelp:
76 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
77 | @echo
78 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \
79 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
80 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Pyjnius.qhcp"
81 | @echo "To view the help file:"
82 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Pyjnius.qhc"
83 |
84 | devhelp:
85 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
86 | @echo
87 | @echo "Build finished."
88 | @echo "To view the help file:"
89 | @echo "# mkdir -p $$HOME/.local/share/devhelp/Pyjnius"
90 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Pyjnius"
91 | @echo "# devhelp"
92 |
93 | epub:
94 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
95 | @echo
96 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
97 |
98 | latex:
99 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
100 | @echo
101 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
102 | @echo "Run \`make' in that directory to run these through (pdf)latex" \
103 | "(use \`make latexpdf' here to do that automatically)."
104 |
105 | latexpdf:
106 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
107 | @echo "Running LaTeX files through pdflatex..."
108 | $(MAKE) -C $(BUILDDIR)/latex all-pdf
109 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
110 |
111 | text:
112 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
113 | @echo
114 | @echo "Build finished. The text files are in $(BUILDDIR)/text."
115 |
116 | man:
117 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
118 | @echo
119 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
120 |
121 | texinfo:
122 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
123 | @echo
124 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
125 | @echo "Run \`make' in that directory to run these through makeinfo" \
126 | "(use \`make info' here to do that automatically)."
127 |
128 | info:
129 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
130 | @echo "Running Texinfo files through makeinfo..."
131 | make -C $(BUILDDIR)/texinfo info
132 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
133 |
134 | gettext:
135 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
136 | @echo
137 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
138 |
139 | changes:
140 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
141 | @echo
142 | @echo "The overview file is in $(BUILDDIR)/changes."
143 |
144 | linkcheck:
145 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
146 | @echo
147 | @echo "Link check complete; look for any errors in the above output " \
148 | "or in $(BUILDDIR)/linkcheck/output.txt."
149 |
150 | doctest:
151 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
152 | @echo "Testing of doctests in the sources finished, look at the " \
153 | "results in $(BUILDDIR)/doctest/output.txt."
154 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | REM Command file for Sphinx documentation
4 |
5 | if "%SPHINXBUILD%" == "" (
6 | set SPHINXBUILD=sphinx-build
7 | )
8 | set BUILDDIR=build
9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
10 | set I18NSPHINXOPTS=%SPHINXOPTS% source
11 | if NOT "%PAPER%" == "" (
12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
14 | )
15 |
16 | if "%1" == "" goto help
17 |
18 | if "%1" == "help" (
19 | :help
20 | echo.Please use `make ^` where ^ is one of
21 | echo. html to make standalone HTML files
22 | echo. dirhtml to make HTML files named index.html in directories
23 | echo. singlehtml to make a single large HTML file
24 | echo. pickle to make pickle files
25 | echo. json to make JSON files
26 | echo. htmlhelp to make HTML files and a HTML help project
27 | echo. qthelp to make HTML files and a qthelp project
28 | echo. devhelp to make HTML files and a Devhelp project
29 | echo. epub to make an epub
30 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
31 | echo. text to make text files
32 | echo. man to make manual pages
33 | echo. texinfo to make Texinfo files
34 | echo. gettext to make PO message catalogs
35 | echo. changes to make an overview over all changed/added/deprecated items
36 | echo. linkcheck to check all external links for integrity
37 | echo. doctest to run all doctests embedded in the documentation if enabled
38 | goto end
39 | )
40 |
41 | if "%1" == "clean" (
42 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
43 | del /q /s %BUILDDIR%\*
44 | goto end
45 | )
46 |
47 | if "%1" == "html" (
48 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
49 | if errorlevel 1 exit /b 1
50 | echo.
51 | echo.Build finished. The HTML pages are in %BUILDDIR%/html.
52 | goto end
53 | )
54 |
55 | if "%1" == "dirhtml" (
56 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
57 | if errorlevel 1 exit /b 1
58 | echo.
59 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
60 | goto end
61 | )
62 |
63 | if "%1" == "singlehtml" (
64 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
65 | if errorlevel 1 exit /b 1
66 | echo.
67 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
68 | goto end
69 | )
70 |
71 | if "%1" == "pickle" (
72 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
73 | if errorlevel 1 exit /b 1
74 | echo.
75 | echo.Build finished; now you can process the pickle files.
76 | goto end
77 | )
78 |
79 | if "%1" == "json" (
80 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
81 | if errorlevel 1 exit /b 1
82 | echo.
83 | echo.Build finished; now you can process the JSON files.
84 | goto end
85 | )
86 |
87 | if "%1" == "htmlhelp" (
88 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
89 | if errorlevel 1 exit /b 1
90 | echo.
91 | echo.Build finished; now you can run HTML Help Workshop with the ^
92 | .hhp project file in %BUILDDIR%/htmlhelp.
93 | goto end
94 | )
95 |
96 | if "%1" == "qthelp" (
97 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
98 | if errorlevel 1 exit /b 1
99 | echo.
100 | echo.Build finished; now you can run "qcollectiongenerator" with the ^
101 | .qhcp project file in %BUILDDIR%/qthelp, like this:
102 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Pyjnius.qhcp
103 | echo.To view the help file:
104 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Pyjnius.ghc
105 | goto end
106 | )
107 |
108 | if "%1" == "devhelp" (
109 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
110 | if errorlevel 1 exit /b 1
111 | echo.
112 | echo.Build finished.
113 | goto end
114 | )
115 |
116 | if "%1" == "epub" (
117 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
118 | if errorlevel 1 exit /b 1
119 | echo.
120 | echo.Build finished. The epub file is in %BUILDDIR%/epub.
121 | goto end
122 | )
123 |
124 | if "%1" == "latex" (
125 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
126 | if errorlevel 1 exit /b 1
127 | echo.
128 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
129 | goto end
130 | )
131 |
132 | if "%1" == "text" (
133 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
134 | if errorlevel 1 exit /b 1
135 | echo.
136 | echo.Build finished. The text files are in %BUILDDIR%/text.
137 | goto end
138 | )
139 |
140 | if "%1" == "man" (
141 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
142 | if errorlevel 1 exit /b 1
143 | echo.
144 | echo.Build finished. The manual pages are in %BUILDDIR%/man.
145 | goto end
146 | )
147 |
148 | if "%1" == "texinfo" (
149 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
150 | if errorlevel 1 exit /b 1
151 | echo.
152 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
153 | goto end
154 | )
155 |
156 | if "%1" == "gettext" (
157 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
158 | if errorlevel 1 exit /b 1
159 | echo.
160 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
161 | goto end
162 | )
163 |
164 | if "%1" == "changes" (
165 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
166 | if errorlevel 1 exit /b 1
167 | echo.
168 | echo.The overview file is in %BUILDDIR%/changes.
169 | goto end
170 | )
171 |
172 | if "%1" == "linkcheck" (
173 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
174 | if errorlevel 1 exit /b 1
175 | echo.
176 | echo.Link check complete; look for any errors in the above output ^
177 | or in %BUILDDIR%/linkcheck/output.txt.
178 | goto end
179 | )
180 |
181 | if "%1" == "doctest" (
182 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
183 | if errorlevel 1 exit /b 1
184 | echo.
185 | echo.Testing of doctests in the sources finished, look at the ^
186 | results in %BUILDDIR%/doctest/output.txt.
187 | goto end
188 | )
189 |
190 | :end
191 |
--------------------------------------------------------------------------------
/docs/requirements.txt:
--------------------------------------------------------------------------------
1 | Sphinx~=7.2.6
2 | furo==2024.8.6
--------------------------------------------------------------------------------
/docs/source/android.rst:
--------------------------------------------------------------------------------
1 | .. _android:
2 |
3 | Android
4 | =======
5 |
6 | Android has a great and extensive API to control devices, your application
7 | etc. Some parts of the Android API are directly accessible with PyJNIus but
8 | some of them require you to code in Java.
9 |
10 | .. note::
11 | Since Android 8.0 (Oreo) the maximum limit for the local references
12 | previously known as "local reference table overflow" after 512 refs
13 | has been lifted, therefore PyJNIus can create proper Java applications
14 | with a lot of local references. `Android JNI tips
15 | `_
16 |
17 | Get the DPI
18 | -----------
19 |
20 | The `DisplayMetrics
21 | `_
22 | contains multiple fields that can return a lot of information about the device's
23 | screen::
24 |
25 | from jnius import autoclass
26 | DisplayMetrics = autoclass('android.util.DisplayMetrics')
27 | metrics = DisplayMetrics()
28 | print('DPI', metrics.getDeviceDensity())
29 |
30 | .. Note ::
31 | To access nested classes, use `$` e.g.
32 | `autoclass('android.provider.MediaStore$Images$Media')`.
33 |
34 | Recording an audio file
35 | -----------------------
36 |
37 | By looking at the `Audio Capture
38 | `_ guide
39 | for Android, you can see the simple steps for recording an audio file.
40 | Let's do it with PyJNIus::
41 |
42 | from jnius import autoclass
43 | from time import sleep
44 |
45 | # get the needed Java classes
46 | MediaRecorder = autoclass('android.media.MediaRecorder')
47 | AudioSource = autoclass('android.media.MediaRecorder$AudioSource')
48 | OutputFormat = autoclass('android.media.MediaRecorder$OutputFormat')
49 | AudioEncoder = autoclass('android.media.MediaRecorder$AudioEncoder')
50 |
51 | # create out recorder
52 | mRecorder = MediaRecorder()
53 | mRecorder.setAudioSource(AudioSource.MIC)
54 | mRecorder.setOutputFormat(OutputFormat.THREE_GPP)
55 | mRecorder.setOutputFile('/sdcard/testrecorder.3gp')
56 | mRecorder.setAudioEncoder(AudioEncoder.AMR_NB)
57 | mRecorder.prepare()
58 |
59 | # record 5 seconds
60 | mRecorder.start()
61 | sleep(5)
62 | mRecorder.stop()
63 | mRecorder.release()
64 |
65 | And tada, you'll have a `/sdcard/testrecorder.3gp` file!
66 |
67 |
68 | Playing an audio file
69 | ---------------------
70 |
71 | Following the previous section on how to record an audio file, you can read it
72 | using the Android Media Player too::
73 |
74 | from jnius import autoclass
75 | from time import sleep
76 |
77 | # get the MediaPlayer java class
78 | MediaPlayer = autoclass('android.media.MediaPlayer')
79 |
80 | # create our player
81 | mPlayer = MediaPlayer()
82 | mPlayer.setDataSource('/sdcard/testrecorder.3gp')
83 | mPlayer.prepare()
84 |
85 | # play
86 | print('duration:', mPlayer.getDuration())
87 | mPlayer.start()
88 | print('current position:', mPlayer.getCurrentPosition())
89 | sleep(5)
90 |
91 | # then after the play:
92 | mPlayer.release()
93 |
94 |
95 | Accessing the Activity
96 | ----------------------
97 |
98 | This example will show how to start a new Intent. Be careful: some Intents
99 | require you to setup parts in the `AndroidManifest.xml` and have some
100 | actions performed within your Activity. This is out of the scope of PyJNIus but
101 | we'll show you what the best approach is for playing with it.
102 |
103 | Using the Python-for-android project, you can access the default
104 | `PythonActivity`. Let's look at an example that demonstrates the
105 | `Intent.ACTION_VIEW`::
106 |
107 | from jnius import cast
108 | from jnius import autoclass
109 |
110 | # import the needed Java class
111 | PythonActivity = autoclass('org.kivy.android.PythonActivity')
112 | Intent = autoclass('android.content.Intent')
113 | Uri = autoclass('android.net.Uri')
114 |
115 | # create the intent
116 | intent = Intent()
117 | intent.setAction(Intent.ACTION_VIEW)
118 | intent.setData(Uri.parse('http://kivy.org'))
119 |
120 | # PythonActivity.mActivity is the instance of the current Activity
121 | # BUT, startActivity is a method from the Activity class, not from our
122 | # PythonActivity.
123 | # We need to cast our class into an activity and use it
124 | currentActivity = cast('android.app.Activity', PythonActivity.mActivity)
125 | currentActivity.startActivity(intent)
126 |
127 | # The website will open.
128 |
129 |
130 | Accelerometer access
131 | --------------------
132 |
133 | The accelerometer is a good example that shows how to write a little
134 | Java code that you can access later with PyJNIus.
135 |
136 | The `SensorManager
137 | `_
138 | lets you access the device's sensors. To use it, you need to register a
139 | `SensorEventListener
140 | `_
141 | and overload 2 abstract methods: `onAccuracyChanged` and `onSensorChanged`.
142 |
143 | Open your python-for-android distribution, go in the `src` directory, and
144 | create a file `org/myapp/Hardware.java`. In this file, you will create
145 | everything needed for accessing the accelerometer::
146 |
147 | package org.myapp;
148 |
149 | import org.kivy.android.PythonActivity;
150 | import android.content.Context;
151 | import android.hardware.Sensor;
152 | import android.hardware.SensorEvent;
153 | import android.hardware.SensorEventListener;
154 | import android.hardware.SensorManager;
155 |
156 | public class Hardware {
157 |
158 | // Contain the last event we got from the listener
159 | static public SensorEvent lastEvent = null;
160 |
161 | // Define a new listener
162 | static class AccelListener implements SensorEventListener {
163 | public void onSensorChanged(SensorEvent ev) {
164 | lastEvent = ev;
165 | }
166 | public void onAccuracyChanged(Sensor sensor , int accuracy) {
167 | }
168 | }
169 |
170 | // Create our listener
171 | static AccelListener accelListener = new AccelListener();
172 |
173 | // Method to activate/deactivate the accelerometer service and listener
174 | static void accelerometerEnable(boolean enable) {
175 | Context context = (Context) PythonActivity.mActivity;
176 | SensorManager sm = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
177 | Sensor accel = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
178 |
179 | if (accel == null)
180 | return;
181 |
182 | if (enable)
183 | sm.registerListener(accelListener, accel, SensorManager.SENSOR_DELAY_GAME);
184 | else
185 | sm.unregisterListener(accelListener, accel);
186 | }
187 | }
188 |
189 | So we created one method named `accelerometerEnable` to activate/deactivate the
190 | listener. And we saved the last event received in `Hardware.lastEvent`.
191 | Now you can use it in PyJNIus::
192 |
193 | from time import sleep
194 | from jnius import autoclass
195 |
196 | Hardware = autoclass('org.myapp.Hardware')
197 |
198 | # activate the accelerometer
199 | Hardware.accelerometerEnable(True)
200 |
201 | # read it
202 | for i in xrange(20):
203 |
204 | # read the last event
205 | lastEvent = Hardware.lastEvent
206 |
207 | # we might not get any events.
208 | if not lastEvent:
209 | continue
210 |
211 | # show the current values!
212 | print(lastEvent.values)
213 |
214 | sleep(.1)
215 |
216 | # don't forget to deactivate it
217 | Hardware.accelerometerEnable(False)
218 |
219 | You'll obtain something like this::
220 |
221 | [-0.0095768067985773087, 9.4235782623291016, 2.2122423648834229]
222 | ...
223 |
224 |
225 | Using TextToSpeech
226 | ------------------
227 |
228 | Same as the audio capture, by looking at the `An introduction to Text-To-Speech in Android
229 | `_ blog post, it's easy to do it
230 | with PyJNIus::
231 |
232 | from jnius import autoclass
233 | Locale = autoclass('java.util.Locale')
234 | PythonActivity = autoclass('org.kivy.android.PythonActivity')
235 | TextToSpeech = autoclass('android.speech.tts.TextToSpeech')
236 | tts = TextToSpeech(PythonActivity.mActivity, None)
237 |
238 | # Play something in english
239 | tts.setLanguage(Locale.US)
240 | tts.speak('Hello World.', TextToSpeech.QUEUE_FLUSH, None)
241 |
242 | # Queue something in french
243 | tts.setLanguage(Locale.FRANCE)
244 | tts.speak('Bonjour tout le monde.', TextToSpeech.QUEUE_ADD, None)
245 |
246 |
--------------------------------------------------------------------------------
/docs/source/building.rst:
--------------------------------------------------------------------------------
1 | .. _building:
2 |
3 | Building PyJNIus
4 | ================
5 |
6 | Building PyJNIus is necessary for development purposes, or if there is no
7 | pre-built binary for your particular platform.
8 |
9 | Like installation of PyJNIus, building PyJNIus requires a `Java Development Kit
10 | `_ (JDK)
11 | to be installed.
12 |
13 | Apart from the JDK, the build requirements for each platform are as follows:
14 |
15 | - Linux: the `GNU Compiler Collection `_ (GCC), e.g. using
16 | `apt-get install build-essentials` on Debian-based distributions.
17 | - Windows: `Microsoft Visual C++ Build Tools `_
18 | (the command-line tools subset of Visual Studio).
19 | For more information or options, see Python's `Windows Compilers wiki
20 | `_.
21 | - macOS: `Xcode command-line tools `_.
22 |
23 | In all cases, after checking out PyJNIus from GitHub, it can be *built* and installed using::
24 |
25 | pip install .
26 |
27 | This installs `Cython `_ (as specified in the
28 | `pyproject.toml `_)
29 | in a Python build environment. On all platforms, if PyJNIus cannot find your JDK, you can set
30 | the `JAVA_HOME` environment variable (this is often needed on Windows).
31 |
32 | If you want to compile the PyJNIus extension within the directory for any development,
33 | just type::
34 |
35 | make
36 |
37 | You can run the tests suite to make sure everything is running right::
38 |
39 | make tests
40 |
41 | In these cases, you may need to have `Cython `_
42 | and `pytest `_ installed in the current Python environment.
--------------------------------------------------------------------------------
/docs/source/contact.rst:
--------------------------------------------------------------------------------
1 | .. _contact:
2 |
3 | Contact Us
4 | ==========
5 |
6 | If you are looking to contact the Kivy Team (who are responsible for managing the
7 | PyJNIus project), including looking for support, please see our
8 | `latest contact details `_.
--------------------------------------------------------------------------------
/docs/source/contribute.rst:
--------------------------------------------------------------------------------
1 | .. _contribute:
2 |
3 | Contribution Guidelines
4 | =======================
5 |
6 | Kivy is a large product used by many thousands of developers for free, but it
7 | is built entirely by the contributions of volunteers. We welcome (and rely on)
8 | users who want to give back to the community by contributing to the project.
9 |
10 | Contributions can come in many forms. To learn more, see our
11 | `latest Contribution Guidelines `_.
--------------------------------------------------------------------------------
/docs/source/faq.rst:
--------------------------------------------------------------------------------
1 | .. _faq:
2 |
3 | FAQ
4 | ===
5 |
6 | PyJNIus has an `online FAQ `_. It contains the answers to
7 | questions that repeatedly come up.
8 |
--------------------------------------------------------------------------------
/docs/source/index.rst:
--------------------------------------------------------------------------------
1 | Welcome to PyJNIus
2 | ==================
3 |
4 | PyJNIus is a `Python `_ library for accessing
5 | `Java `_ classes using the
6 | `Java Native Interface `
7 | (JNI).
8 |
9 | It either starts a new `Java Virtual machine `_
10 | (JVM) inside the process, or retrieves the already surrounding JVM (for example on Android).
11 |
12 | PyJNIus is managed by the `Kivy Team `_ and can be
13 | used with `python-for-android `_.
14 |
15 | PyJNIus is released and distributed under the terms of the MIT license. You should have received a
16 | copy of the MIT license alongside your Kivy distribution. Our
17 | `latest license `_
18 | is also available.
19 |
20 |
21 | This documentation is divided into differents parts. We recommend you to start
22 | with :ref:`installation`, and then head over to the :ref:`quickstart`. You can
23 | also check :ref:`android` for specific example for the Android platform. If
24 | you'd rather dive into the internals of PyJNIus, check out the :ref:`api`
25 | documentation.
26 |
27 | .. toctree::
28 | :maxdepth: 2
29 |
30 | installation
31 | quickstart
32 | android
33 | api
34 | packaging
35 | contact
36 | contribute
37 | faq
38 |
39 | Indices and tables
40 | ==================
41 |
42 | * :ref:`genindex`
43 | * :ref:`modindex`
44 | * :ref:`search`
45 |
46 |
--------------------------------------------------------------------------------
/docs/source/installation.rst:
--------------------------------------------------------------------------------
1 | .. _installation:
2 |
3 | Installation
4 | ============
5 |
6 | PyJNIus has pre-compiled binaries on PyPi for recent Python versions on Linux,
7 | macOS and Windows.
8 |
9 | On each platform::
10 |
11 | pip install pyjnius
12 |
13 | should successfully install the package.
14 |
15 | If there is no pre-compiled binary available, pip install will aim to compile
16 | a binary on your operating system. For more information see the :ref:`building`
17 | documentation.
18 |
19 | You will need the Java JDK installed (`OpenJDK `_ is fine).
20 | PyJNIus searches for Java in the usual places on each operating system. If PyJNIus
21 | cannot find Java, set the `JAVA_HOME` environment variable (this is often needed
22 | `on Windows `_).
23 |
24 | Installation for Android
25 | ------------------------
26 |
27 | To use pyjnius in an Android app, you must include it in your compiled
28 | Python distribution. This is done automatically if you build a `Kivy
29 | `__ app, but you can also add it to your
30 | requirements explicitly as follows.
31 |
32 | If you use `buildozer
33 | `__, add pyjnius to your
34 | requirements in buildozer.spec::
35 |
36 | requirements = pyjnius
37 |
38 | If you use `python-for-android
39 | `__ directly, add
40 | pyjnius to the requirements argument when creating a dist or apk::
41 |
42 | p4a apk --requirements=pyjnius
43 |
44 |
45 | Installation for Conda
46 | ----------------------
47 |
48 | Similar to PIP there is a package manager for
49 | `Anaconda ` called Conda.
50 | An unofficial compiled distributions of PyJNIus for Conda supported
51 | platforms you can find at https://anaconda.org/conda-forge/pyjnius.
52 |
53 | You can install ``pyjnius`` with this command::
54 |
55 | conda install -c conda-forge pyjnius
56 |
57 | Or if you want a specific package label e.g. ``gcc7``::
58 |
59 | conda install -c conda-forge/label/gcc7 pyjnius
60 |
--------------------------------------------------------------------------------
/docs/source/packaging.rst:
--------------------------------------------------------------------------------
1 | .. _packaging:
2 |
3 | Packaging
4 | =========
5 |
6 | For Packaging, we suggest use of `PyInstaller `_.
7 | With these simple steps we will create a simple executable containing PyJNIus
8 | that prints the path of currently used Java. These steps assume you have
9 | a supported version of Python for PyJNIus and PyInstaller available together
10 | with Java installed (necessary for running the application).
11 |
12 | main.py
13 | -------
14 |
15 | .. code:: python
16 |
17 | from jnius import autoclass
18 |
19 | if __name__ == '__main__':
20 | print(autoclass('java.lang.System').getProperty('java.home'))
21 |
22 | This will be our ``main.py`` file. You can now call PyInstaller to create
23 | a basic ``.spec`` file which contains basic instructions for PyInstaller with::
24 |
25 | pyinstaller main.py
26 |
27 | main.spec
28 | ---------
29 |
30 | The created ``.spec`` file might look like this::
31 |
32 | # -*- mode: python -*-
33 |
34 | block_cipher = None
35 |
36 |
37 | a = Analysis(
38 | ['main.py'],
39 | pathex=[''],
40 | binaries=None,
41 | datas=None,
42 | hiddenimports=[],
43 | hookspath=[],
44 | runtime_hooks=[],
45 | excludes=[],
46 | win_no_prefer_redirects=False,
47 | win_private_assemblies=False,
48 | cipher=block_cipher
49 | )
50 |
51 | pyz = PYZ(
52 | a.pure,
53 | a.zipped_data,
54 | cipher=block_cipher
55 | )
56 |
57 | exe = EXE(
58 | pyz,
59 | a.scripts,
60 | exclude_binaries=True,
61 | name='main',
62 | debug=False,
63 | strip=False,
64 | upx=True,
65 | console=True
66 | )
67 |
68 | coll = COLLECT(
69 | exe,
70 | a.binaries,
71 | a.zipfiles,
72 | a.datas,
73 | strip=False,
74 | upx=True,
75 | name='main'
76 | )
77 |
78 | Notice the ``Analysis`` section, it contains details for what Python related
79 | files to collect e.g. the ``main.py`` file. For PyJNIus to work you need to
80 | include the ``jnius_config`` module to the ``hiddenimports`` list, otherwise
81 | you will get a ``ImportError: No module named jnius_config``::
82 |
83 | ...
84 |
85 | a = Analysis(
86 | ['main.py'],
87 | pathex=[''],
88 | binaries=None,
89 | datas=None,
90 | hiddenimports=['jnius_config'],
91 | hookspath=[],
92 | runtime_hooks=[],
93 | excludes=[],
94 | win_no_prefer_redirects=False,
95 | win_private_assemblies=False,
96 | cipher=block_cipher
97 | )
98 |
99 | ...
100 |
101 | After the ``.spec`` file is ready, in our case it's by default called by the
102 | name of the ``.py`` file, we need to direct PyInstaller to use that file::
103 |
104 | pyinstaller main.spec
105 |
106 | This will create a folder with all required ``.dll`` and ``.pyd`` or ``.so``
107 | shared libraries and other necessary files for our application and for Python
108 | itself.
109 |
110 | Running
111 | -------
112 |
113 | We have the application ready, but the "problem" is PyJNIus doesn't detect
114 | any installed Java on your computer (yet). Therefore if you try to run the
115 | application, it'll crash with a ``ImportError: DLL load failed: ...``.
116 | For this simple example if you can see ``jnius.jnius.pyd`` or
117 | ``jnius.jnius.so`` in the final folder with ``main.exe`` (or just ``main``),
118 | the error indicates that the application could not find Java Virtual Machine.
119 |
120 | The Java Virtual Machine is in simple terms said another necessary shared
121 | library your application needs to load (``jvm.dll`` or ``libjvm.so``).
122 |
123 | On Windows this file might be in a folder similar to this::
124 |
125 | C:\Program Files\Java\jdk1.7.0_79\jre\bin\server
126 |
127 | and you need to include the folder to the system ``PATH`` environment variable
128 | with this command::
129 |
130 | set PATH=%PATH%;C:\\Program Files\\Java\\jdk1.7.0_79\\jre\\bin\\server
131 |
132 | After the ``jvm.dll`` or ``libjvm.so`` becomes available, you can safely
133 | try to run your application::
134 |
135 | main.exe
136 |
137 | and you should get an output similar to this::
138 |
139 | C:\Program Files\Java\jdk1.7.0_79\jre
140 |
--------------------------------------------------------------------------------
/docs/source/quickstart.rst:
--------------------------------------------------------------------------------
1 | .. _quickstart:
2 |
3 | Quickstart
4 | ==========
5 |
6 | Eager to get started? This page will give you a good introduction to Pyjnius. It assumes
7 | you have already PyJNIus installed. If you do not, ensure you have a Java JDK installed,
8 | then try `pip install pyjnius` - you can head over to the :ref:`installation` section
9 | for more information.
10 |
11 | A minimal example
12 | -----------------
13 |
14 | A minimal PyJNIus example looks something like this::
15 |
16 | from jnius import autoclass
17 |
18 | Stack = autoclass('java.util.Stack')
19 | stack = Stack()
20 | stack.push('hello')
21 | stack.push('world')
22 |
23 | print(stack.pop()) # --> 'world'
24 | print(stack.pop()) # --> 'hello'
25 |
26 | Just save it as `test.py` (or something similar) and run it with your Python
27 | interpreter. Make sure not to call your application `jnius.py` because it would
28 | conflict with PyJNIus itself::
29 |
30 | $ python test.py
31 | world
32 | hello
33 |
34 | To load nested java classes, use the "$" separator as so::
35 |
36 | version = autoclass("android.os.Build$VERSION")
37 | base_os = version.BASE_OS
38 |
39 |
40 | Automatic recursive inspection
41 | ------------------------------
42 |
43 | PyJNIus uses Java reflection to give you a new autoclass() if the return type is
44 | not a native type. Let's see this example::
45 |
46 | System = autoclass('java.lang.System')
47 | System.out.println('Hello World')
48 |
49 | We only declared the first System class, but we are able to use all the static
50 | fields and methods naturally. Let's go deeper::
51 |
52 | >>> System = autoclass('java.lang.System')
53 | >>> System
54 |
55 | >>> System.out
56 |
57 | >>> System.out.println
58 |
59 |
60 | The recursive reflection always gives you an appropriate object that reflects the
61 | returned Java object.
62 |
--------------------------------------------------------------------------------
/examples/arraylists/arraylist.java:
--------------------------------------------------------------------------------
1 | // javac arraylist.java
2 | // java arraylist
3 |
4 | import java.lang.String;
5 | import java.util.List;
6 | import java.util.Arrays;
7 | import java.util.ArrayList;
8 |
9 |
10 | public class arraylist {
11 | public static void main(String[] args) {
12 | // Object based empty ArrayList
13 | ArrayList jlist = new ArrayList();
14 | System.out.println(jlist);
15 | System.out.println(jlist.size());
16 |
17 | // String array
18 | String[] str_array = {"a", "b", "c"};
19 | System.out.println(str_array.toString());
20 | System.out.println(str_array.length);
21 |
22 | // add the array of strings to the list
23 | jlist.add(str_array);
24 | System.out.println(jlist.toString());
25 | System.out.println(jlist.size());
26 |
27 | // create a new ArrayList from String array
28 | ArrayList str_list = new ArrayList(
29 | Arrays.asList(str_array.toString())
30 | );
31 | jlist.add(str_list);
32 | System.out.println(jlist.toString());
33 | System.out.println(jlist.size());
34 |
35 | // add an empty Object to ArrayList
36 | jlist.add(new Object());
37 | System.out.println(jlist.toString());
38 | System.out.println(jlist.size());
39 |
40 | // new ArrayList to wrap everything up
41 | ArrayList plain_list = new ArrayList();
42 | plain_list.add(str_array);
43 | plain_list.add(str_list);
44 | plain_list.add(jlist);
45 | System.out.println(plain_list.toString());
46 | System.out.println(plain_list.size());
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/examples/arraylists/arraylist.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=invalid-name
2 | '''
3 | Example of nested ArrayList and passing empty tuple/list to Java functions.
4 | '''
5 |
6 | from __future__ import unicode_literals, print_function
7 | from jnius import autoclass, cast # pylint: disable=import-error
8 |
9 | String = autoclass('java.lang.String')
10 | List = autoclass('java.util.List')
11 | Arrays = autoclass('java.util.Arrays')
12 | ArrayList = autoclass('java.util.ArrayList')
13 | JavaArray = autoclass('java.lang.reflect.Array')
14 | Object = autoclass('java.lang.Object')
15 |
16 |
17 | def sep_print(*args):
18 | '''
19 | Separate args because in <80char console (e.g. Windows)
20 | is the output barely readable with [[, @, ;, ,, ...
21 | '''
22 | print(*args)
23 | print('-' * 10)
24 |
25 |
26 | # Object based empty ArrayList
27 | jlist = ArrayList()
28 | sep_print(jlist, jlist.toString(), len(jlist))
29 |
30 | # String array
31 | str_array = JavaArray.newInstance(String, 3)
32 | for i, item in enumerate(('a', 'b', 'c')):
33 | str_array[i] = String(item)
34 | sep_print(str_array, len(str_array))
35 |
36 | # add the array of strings to the list
37 | jlist.add(str_array)
38 | sep_print(jlist, jlist.toString(), len(jlist))
39 |
40 | # create a new ArrayList from String array
41 | str_list = ArrayList(Arrays.asList(str_array))
42 | jlist.add(str_list)
43 | sep_print(jlist, jlist.toString(), len(jlist))
44 |
45 | # add an empty Object to ArrayList
46 | jlist.add(Object())
47 | sep_print(jlist, jlist.toString(), len(jlist))
48 |
49 | # new ArrayList to wrap everything up
50 | plain_list = ArrayList()
51 | plain_list.add(str_array)
52 | plain_list.add(str_list)
53 | plain_list.add(jlist)
54 | sep_print(plain_list, plain_list.toString(), len(plain_list))
55 |
--------------------------------------------------------------------------------
/jnius/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | PyJNIus
3 | =======
4 |
5 | Accessing Java classes from Python.
6 |
7 | All the documentation is available at: http://pyjnius.readthedocs.org
8 | '''
9 |
10 | __version__ = '1.6.1'
11 |
12 | from .env import get_java_setup
13 |
14 | import os
15 | import sys
16 | if sys.platform == 'win32' and sys.version_info >= (3, 8):
17 | path = os.path.dirname(__file__)
18 | java = get_java_setup(sys.platform)
19 | jdk_home = java.get_javahome()
20 | with os.add_dll_directory(path):
21 | for suffix in (
22 | ('bin', 'client'),
23 | ('bin', 'server'),
24 | ('bin', 'default'),
25 | ('jre', 'bin', 'client'),
26 | ('jre', 'bin', 'server'),
27 | ('jre', 'bin', 'default'),
28 | ):
29 | path = os.path.join(jdk_home, *suffix)
30 | if not os.path.isdir(path):
31 | continue
32 |
33 | with os.add_dll_directory(path):
34 | try:
35 | from .jnius import * # noqa
36 | from .reflect import * # noqa
37 | except Exception as e:
38 | pass
39 | else:
40 | break
41 | else:
42 | raise Exception("Unable to create jni env, no jvm dll found.")
43 | else:
44 | from .jnius import * # noqa
45 | from .reflect import * # noqa
46 |
47 | # XXX monkey patch methods that cannot be in cython.
48 | # Cython doesn't allow to set new attribute on methods it compiled
49 |
50 | HASHCODE_MAX = 2 ** 31 - 1
51 |
52 |
53 | class PythonJavaClass_(PythonJavaClass, metaclass=MetaJavaBase):
54 |
55 | @java_method('()I', name='hashCode')
56 | def hashCode(self):
57 | return id(self) % HASHCODE_MAX
58 |
59 | @java_method('()Ljava/lang/String;', name='hashCode')
60 | def hashCode_(self):
61 | return '{}'.format(self.hashCode())
62 |
63 | @java_method('()Ljava/lang/String;', name='toString')
64 | def toString(self):
65 | return repr(self)
66 |
67 | @java_method('(Ljava/lang/Object;)Z', name='equals')
68 | def equals(self, other):
69 | return self.hashCode() == other.hashCode()
70 |
71 |
72 | PythonJavaClass = PythonJavaClass_
73 |
74 |
75 | # from https://gist.github.com/tito/09c42fb4767721dc323d
76 | import os
77 | if "ANDROID_ARGUMENT" in os.environ:
78 | # on android, catch all exception to ensure about a jnius.detach
79 | import threading
80 | import jnius
81 | orig_thread_run = threading.Thread.run
82 |
83 | def jnius_thread_hook(*args, **kwargs):
84 | try:
85 | return orig_thread_run(*args, **kwargs)
86 | finally:
87 | jnius.detach()
88 |
89 | threading.Thread.run = jnius_thread_hook
90 |
--------------------------------------------------------------------------------
/jnius/jnius.pyx:
--------------------------------------------------------------------------------
1 |
2 | '''
3 | Java wrapper
4 | ============
5 |
6 | With this module, you can create Python class that reflects a Java class, and use
7 | it directly in Python.
8 |
9 | Example with static method
10 | --------------------------
11 |
12 | Java::
13 |
14 | package org.test;
15 | public class Hardware {
16 | static int getDPI() {
17 | return metrics.densityDpi;
18 | }
19 | }
20 |
21 | Python::
22 |
23 | class Hardware(JavaClass):
24 | __metaclass__ = MetaJavaClass
25 | __javaclass__ = 'org/test/Hardware'
26 | getDPI = JavaStaticMethod('()I')
27 |
28 | Hardware.getDPI()
29 |
30 |
31 | Example with instance method
32 | ----------------------------
33 |
34 | Java::
35 |
36 | package org.test;
37 | public class Action {
38 | public String getName() {
39 | return new String("Hello world")
40 | }
41 | }
42 |
43 | Python::
44 |
45 | class Action(JavaClass):
46 | __metaclass__ = MetaJavaClass
47 | __javaclass__ = 'org/test/Action'
48 | getName = JavaMethod('()Ljava/lang/String;')
49 |
50 | action = Action()
51 | print action.getName()
52 | # will output Hello World
53 |
54 |
55 | Example with static/instance field
56 | ----------------------------------
57 |
58 | Java::
59 |
60 | package org.test;
61 | public class Test {
62 | public static String field1 = new String("hello");
63 | public String field2;
64 |
65 | public Test() {
66 | this.field2 = new String("world");
67 | }
68 | }
69 |
70 | Python::
71 |
72 | class Test(JavaClass):
73 | __metaclass__ = MetaJavaClass
74 | __javaclass__ = 'org/test/Test'
75 |
76 | field1 = JavaStaticField('Ljava/lang/String;')
77 | field2 = JavaField('Ljava/lang/String;')
78 |
79 | # access directly to the static field
80 | print Test.field1
81 |
82 | # create the instance, and access to the instance field
83 | test = Test()
84 | print test.field2
85 |
86 | '''
87 |
88 | __all__ = ('JavaObject', 'JavaClass', 'JavaMethod', 'JavaField',
89 | 'JavaStaticMethod', 'JavaStaticField', 'JavaMultipleMethod',
90 | 'MetaJavaBase', 'MetaJavaClass', 'JavaException', 'cast',
91 | 'find_javaclass', 'PythonJavaClass', 'java_method', 'detach')
92 |
93 | from libc.stdlib cimport malloc, free
94 | from functools import partial
95 | import sys
96 | import traceback
97 |
98 | include "jnius_compat.pxi"
99 | include "jni.pxi"
100 | include "config.pxi"
101 |
102 | IF JNIUS_PLATFORM == "android":
103 | include "jnius_jvm_android.pxi"
104 | ELIF JNIUS_PLATFORM == "win32":
105 | include "jnius_jvm_desktop.pxi"
106 | ELSE:
107 | include "jnius_jvm_dlopen.pxi"
108 |
109 | # from Cython 3.0, in the MetaJavaClass, this is accessed as _JavaClass__cls_storage
110 | # see https://cython.readthedocs.io/en/latest/src/userguide/migrating_to_cy30.html#class-private-name-mangling
111 | cdef CLS_STORAGE_NAME = '_JavaClass__cls_storage' if JNIUS_CYTHON_3 else '__cls_storage'
112 |
113 | include "jnius_env.pxi"
114 | include "jnius_utils.pxi"
115 | include "jnius_conversion.pxi"
116 | include "jnius_localref.pxi"
117 |
118 | include "jnius_nativetypes3.pxi"
119 |
120 | include "jnius_export_func.pxi"
121 | include "jnius_export_class.pxi"
122 |
123 | include "jnius_proxy.pxi"
124 |
--------------------------------------------------------------------------------
/jnius/jnius_compat.pxi:
--------------------------------------------------------------------------------
1 | '''
2 | Handle Python 2 vs 3 differences here.
3 | '''
4 |
5 | # because Cython's basestring doesn't work with isinstance() properly
6 | # and has differences between Python 2 and Python 3 runtime behavior
7 | # so it's not really usable unless some bug in the upstream is fixed
8 | # (tested with Cython==0.29.2)
9 | cdef tuple base_string = (bytes, str)
10 |
11 |
12 | cdef unicode to_unicode(object arg):
13 | '''
14 | Accept full object as a type to prevent py2/py3 differences
15 | and throw an exception in case of misusing this function.
16 | '''
17 |
18 | if not isinstance(arg, base_string):
19 | raise JavaException(
20 | 'Argument {!r} is not of a text type.'.format(arg)
21 | )
22 |
23 | cdef unicode result
24 | if isinstance(arg, bytes):
25 | result = (arg).decode('utf-8')
26 | else:
27 | result = arg
28 | return result
29 |
--------------------------------------------------------------------------------
/jnius/jnius_env.pxi:
--------------------------------------------------------------------------------
1 |
2 | cdef JNIEnv *default_env = NULL
3 |
4 | cdef extern int gettid()
5 | cdef JavaVM *jvm = NULL
6 |
7 | cdef JNIEnv *get_jnienv() except NULL:
8 | global default_env
9 | # first call, init.
10 | if default_env == NULL:
11 | default_env = get_platform_jnienv()
12 | if default_env == NULL:
13 | return NULL
14 | default_env[0].GetJavaVM(default_env, &jvm)
15 |
16 | # return the current env attached to the thread
17 | # XXX it threads are created from C (not java), we'll leak here.
18 | cdef JNIEnv *env = NULL
19 | jvm[0].AttachCurrentThread(jvm, &env, NULL)
20 | return env
21 |
22 |
23 | def detach():
24 | jvm[0].DetachCurrentThread(jvm)
25 |
26 |
--------------------------------------------------------------------------------
/jnius/jnius_export_func.pxi:
--------------------------------------------------------------------------------
1 | def cast(destclass, obj):
2 | cdef JavaClass jc
3 | cdef JavaClass jobj = obj
4 | from .reflect import autoclass
5 | if isinstance(destclass, str):
6 | jc = autoclass(destclass)(noinstance=True)
7 | else:
8 | jc = destclass(noinstance=True)
9 | jc.instanciate_from(jobj.j_self)
10 | return jc
11 |
12 |
13 | def find_javaclass(namestr):
14 | namestr = namestr.replace('.', '/')
15 | cdef bytes name = str_for_c(namestr)
16 | from .reflect import Class
17 | cdef JavaClass cls
18 | cdef jclass jc
19 | cdef JNIEnv *j_env = get_jnienv()
20 |
21 | jc = j_env[0].FindClass(j_env, name)
22 | check_exception(j_env)
23 |
24 | cls = Class(noinstance=True)
25 | cls.instanciate_from(create_local_ref(j_env, jc))
26 | j_env[0].DeleteLocalRef(j_env, jc)
27 | return cls
28 |
29 |
--------------------------------------------------------------------------------
/jnius/jnius_jvm_android.pxi:
--------------------------------------------------------------------------------
1 | # on android, rely on SDL to get the JNI env
2 | cdef extern JNIEnv *SDL_AndroidGetJNIEnv()
3 |
4 |
5 | cdef JNIEnv *get_platform_jnienv() except NULL:
6 | return SDL_AndroidGetJNIEnv()
7 |
--------------------------------------------------------------------------------
/jnius/jnius_jvm_desktop.pxi:
--------------------------------------------------------------------------------
1 | import sys
2 | import os
3 | from os.path import join
4 | from jnius.env import get_java_setup
5 |
6 | # on desktop, we need to create an env :)
7 | # example taken from http://www.inonit.com/cygwin/jni/invocationApi/c.html
8 |
9 | cdef extern jint __stdcall JNI_CreateJavaVM(JavaVM **pvm, void **penv, void *args)
10 | cdef extern from "jni.h":
11 | int JNI_VERSION_1_4
12 | int JNI_OK
13 | jboolean JNI_FALSE
14 | ctypedef struct JavaVMInitArgs:
15 | jint version
16 | jint nOptions
17 | jboolean ignoreUnrecognized
18 | JavaVMOption *options
19 | ctypedef struct JavaVMOption:
20 | char *optionString
21 | void *extraInfo
22 |
23 | cdef JNIEnv *_platform_default_env = NULL
24 |
25 | cdef void create_jnienv() except *:
26 | cdef JavaVM* jvm
27 | cdef JavaVMInitArgs args
28 | cdef JavaVMOption *options
29 | cdef int ret
30 | cdef bytes py_bytes
31 | import jnius_config
32 |
33 | optarr = jnius_config.options
34 | cp = jnius_config.expand_classpath()
35 | optarr.append("-Djava.class.path={0}".format(cp))
36 |
37 | optarr = [str_for_c(x) for x in optarr]
38 | options = malloc(sizeof(JavaVMOption) * len(optarr))
39 | for i, opt in enumerate(optarr):
40 | options[i].optionString = (opt)
41 | options[i].extraInfo = NULL
42 |
43 | args.version = JNI_VERSION_1_4
44 | args.options = options
45 | args.nOptions = len(optarr)
46 | args.ignoreUnrecognized = JNI_FALSE
47 |
48 | attempted = []
49 | if sys.version_info >= (3, 8):
50 | # uh, let's see if this works and cleanup later
51 | java = get_java_setup('win32')
52 | jdk_home = java.get_javahome()
53 | for suffix in (
54 | ('bin', 'client'),
55 | ('bin', 'server'),
56 | ('bin', 'default'),
57 | ('jre', 'bin', 'client'),
58 | ('jre', 'bin', 'server'),
59 | ('jre', 'bin', 'default'),
60 | ):
61 | path = join(jdk_home, *suffix)
62 | if not os.path.isdir(path):
63 | continue
64 | with os.add_dll_directory(path):
65 | attempted.append(path)
66 | try:
67 | ret = JNI_CreateJavaVM(&jvm, &_platform_default_env, &args)
68 | except Exception as e:
69 | pass
70 | else:
71 | break
72 | else:
73 | if len(attempted) > 0:
74 | raise Exception("Unable to create jni env, no jvm dll found in %s" % str(attempted))
75 | else:
76 | raise Exception("Unable to create jni env, no valid java library paths were found in %s, perhaps you need to update JAVA_HOME" % jdk_home)
77 | else:
78 | ret = JNI_CreateJavaVM(&jvm, &_platform_default_env, &args)
79 |
80 | free(options)
81 |
82 | if ret != JNI_OK:
83 | raise SystemError("JVM failed to start")
84 |
85 | jnius_config.vm_running = True
86 | import traceback
87 | jnius_config.vm_started_at = ''.join(traceback.format_stack())
88 |
89 | cdef JNIEnv *get_platform_jnienv() except NULL:
90 | if _platform_default_env == NULL:
91 | create_jnienv()
92 | return _platform_default_env
93 |
--------------------------------------------------------------------------------
/jnius/jnius_jvm_dlopen.pxi:
--------------------------------------------------------------------------------
1 | include "config.pxi"
2 | import os
3 | from shlex import split
4 | from subprocess import check_output, CalledProcessError
5 | from os.path import dirname, join, exists
6 | from os import readlink
7 | from sys import platform
8 | from .env import get_java_setup
9 |
10 |
11 | cdef extern from 'dlfcn.h' nogil:
12 | void* dlopen(const char *filename, int flag)
13 | char *dlerror()
14 | void *dlsym(void *handle, const char *symbol)
15 | int dlclose(void *handle)
16 |
17 | unsigned int RTLD_LAZY
18 | unsigned int RTLD_NOW
19 | unsigned int RTLD_GLOBAL
20 | unsigned int RTLD_LOCAL
21 | unsigned int RTLD_NODELETE
22 | unsigned int RTLD_NOLOAD
23 | unsigned int RTLD_DEEPBIND
24 |
25 | unsigned int RTLD_DEFAULT
26 | long unsigned int RTLD_NEXT
27 |
28 |
29 | cdef extern from "jni.h":
30 | int JNI_VERSION_1_6
31 | int JNI_OK
32 | jboolean JNI_FALSE
33 | ctypedef struct JavaVMInitArgs:
34 | jint version
35 | jint nOptions
36 | jboolean ignoreUnrecognized
37 | JavaVMOption *options
38 | ctypedef struct JavaVMOption:
39 | char *optionString
40 | void *extraInfo
41 |
42 | cdef JNIEnv *_platform_default_env = NULL
43 |
44 |
45 | cdef void create_jnienv() except *:
46 | cdef JavaVM* jvm
47 | cdef JavaVMInitArgs args
48 | cdef JavaVMOption *options
49 | cdef int ret
50 | cdef bytes py_bytes
51 | cdef void *handle
52 | import jnius_config
53 |
54 | JAVA_LOCATION = get_java_setup()
55 | cdef str java_lib = JAVA_LOCATION.get_jnius_lib_location()
56 |
57 | lib_path = str_for_c(java_lib)
58 |
59 | handle = dlopen(lib_path, RTLD_NOW | RTLD_GLOBAL)
60 |
61 | if handle == NULL:
62 | raise SystemError("Error calling dlopen({0}): {1}".format(lib_path, dlerror()))
63 |
64 | cdef void *jniCreateJVM = dlsym(handle, b"JNI_CreateJavaVM")
65 |
66 | if jniCreateJVM == NULL:
67 | raise SystemError("Error calling dlfcn for JNI_CreateJavaVM: {0}".format(dlerror()))
68 |
69 | optarr = jnius_config.options
70 | optarr.append("-Djava.class.path=" + jnius_config.expand_classpath())
71 |
72 | optarr = [str_for_c(x) for x in optarr]
73 | options = malloc(sizeof(JavaVMOption) * len(optarr))
74 | for i, opt in enumerate(optarr):
75 | options[i].optionString = (opt)
76 | options[i].extraInfo = NULL
77 |
78 | args.version = JNI_VERSION_1_6
79 | args.options = options
80 | args.nOptions = len(optarr)
81 | args.ignoreUnrecognized = JNI_FALSE
82 |
83 | ret = ( jniCreateJVM)(&jvm, &_platform_default_env, &args)
84 | free(options)
85 |
86 | if ret != JNI_OK:
87 | raise SystemError("JVM failed to start: {0}".format(ret))
88 |
89 | jnius_config.vm_running = True
90 | import traceback
91 | jnius_config.vm_started_at = ''.join(traceback.format_stack())
92 |
93 | cdef JNIEnv *get_platform_jnienv() except NULL:
94 | if _platform_default_env == NULL:
95 | create_jnienv()
96 | return _platform_default_env
97 |
--------------------------------------------------------------------------------
/jnius/jnius_localref.pxi:
--------------------------------------------------------------------------------
1 | cdef class LocalRef:
2 | cdef jobject obj
3 |
4 | def __cinit__(self):
5 | self.obj = NULL
6 |
7 | def __dealloc__(self):
8 | cdef JNIEnv *j_env
9 | if self.obj != NULL:
10 | j_env = get_jnienv()
11 | j_env[0].DeleteGlobalRef(j_env, self.obj)
12 | self.obj = NULL
13 |
14 | cdef void create(self, JNIEnv *env, jobject obj) except *:
15 | self.obj = env[0].NewGlobalRef(env, obj)
16 |
17 | def __repr__(self):
18 | return ''.format(
19 | self.obj, id(self))
20 |
21 |
22 | cdef LocalRef create_local_ref(JNIEnv *env, jobject obj):
23 | cdef LocalRef ret = LocalRef()
24 | ret.create(env, obj)
25 | return ret
26 |
27 |
--------------------------------------------------------------------------------
/jnius/jnius_nativetypes3.pxi:
--------------------------------------------------------------------------------
1 |
2 | cdef python_op(int op, object a, object b):
3 | if op == 0:
4 | return a < b
5 | elif op == 1:
6 | return a <= b
7 | elif op == 2:
8 | return a == b
9 | elif op == 3:
10 | return a >= b
11 | elif op == 4:
12 | return a > b
13 | elif op == 5:
14 | return a != b
15 |
16 | cdef class ByteArray:
17 | cdef LocalRef _jobject
18 | cdef long _size
19 | cdef unsigned char *_buf
20 | cdef unsigned char[:] _arr
21 |
22 | def __cinit__(self):
23 | self._size = 0
24 | self._buf = NULL
25 | self._arr = None
26 |
27 | def __dealloc__(self):
28 | cdef JNIEnv *j_env
29 | if self._buf != NULL:
30 | j_env = get_jnienv()
31 | j_env[0].ReleaseByteArrayElements(
32 | j_env, self._jobject.obj, self._buf, 0)
33 | self._buf = NULL
34 | self._jobject = None
35 |
36 | cdef void set_buffer(self, JNIEnv *env, jobject obj, long size, jbyte *buf) except *:
37 | if self._buf != NULL:
38 | raise Exception('Cannot call set_buffer() twice.')
39 | self._jobject = LocalRef()
40 | self._jobject.create(env, obj)
41 | self._size = size
42 | self._buf = buf
43 | if size:
44 | self._arr = self._buf
45 |
46 | def __str__(self):
47 | return ''.format(
48 | self._size, id(self))
49 |
50 | def __len__(self):
51 | return self._size
52 |
53 | def __getitem__(self, index):
54 | cdef long xx
55 | if isinstance(index, slice):
56 | val = []
57 | if self._size:
58 | (start, stop, step) = index.indices(len(self._arr))
59 | for x in range(start, stop, step):
60 | xx = x
61 | val.append(self._arr[xx])
62 | return val
63 | else:
64 | xx = index
65 | return self._arr[xx]
66 |
67 | def __richcmp__(self, other, op):
68 | cdef ByteArray b_other
69 | if isinstance(other, (list, tuple)):
70 | return python_op(op, self.tolist(), other)
71 | elif isinstance(other, ByteArray):
72 | b_other = other
73 | return python_op(op, self.tostring(), other.tostring())
74 | else:
75 | return False
76 |
77 | def tolist(self):
78 | return list(self[:])
79 |
80 | def tostring(self):
81 | return self._buf[:self._size]
82 |
--------------------------------------------------------------------------------
/jnius/jnius_proxy.pxi:
--------------------------------------------------------------------------------
1 | class java_method(object):
2 | def __init__(self, signature, name=None):
3 | super(java_method, self).__init__()
4 | self.signature = signature
5 | self.name = name
6 |
7 | def __get__(self, instance, instancetype):
8 | return partial(self.__call__, instance)
9 |
10 | def __call__(self, f):
11 | f.__javasignature__ = self.signature
12 | f.__javaname__ = self.name
13 | return f
14 |
15 |
16 | cdef class PythonJavaClass(object):
17 | '''
18 | Base class to create a java class from python
19 | '''
20 | cdef jclass j_cls
21 | cdef public object j_self
22 |
23 | def __cinit__(self, *args):
24 | self.j_cls = NULL
25 | self.j_self = None
26 |
27 | def __init__(self, *args, **kwargs):
28 | self._init_j_self_ptr()
29 |
30 | def _init_j_self_ptr(self):
31 | javacontext = 'system'
32 | if hasattr(self, '__javacontext__'):
33 | javacontext = self.__javacontext__
34 | self.j_self = create_proxy_instance(get_jnienv(), self,
35 | self.__javainterfaces__, javacontext)
36 |
37 | # discover all the java method implemented
38 | self.__javamethods__ = {}
39 | for x in dir(self):
40 | attr = getattr(self, x)
41 | if not callable(attr):
42 | continue
43 | if not hasattr(attr, '__javasignature__'):
44 | continue
45 | signature = parse_definition(attr.__javasignature__)
46 | self.__javamethods__[(attr.__javaname__ or x, signature)] = attr
47 |
48 | def invoke(self, method, *args):
49 | try:
50 | ret = self._invoke(method, *args)
51 | return ret
52 | except Exception:
53 | traceback.print_exc()
54 | return None
55 |
56 | def _invoke(self, method, *args):
57 | from .reflect import get_signature
58 | # search the java method
59 |
60 | ret_signature = get_signature(method.getReturnType())
61 | args_signature = tuple([get_signature(x) for x in method.getParameterTypes()])
62 | method_name = method.getName()
63 |
64 | key = (method_name, (ret_signature, args_signature))
65 |
66 | py_method = self.__javamethods__.get(key, None)
67 | if not py_method:
68 | print(''.join([
69 | '\n===== Python/java method missing ======',
70 | '\nPython class:', repr(self),
71 | '\nJava method name:', method_name,
72 | '\nSignature: ({}){}'.format(''.join(args_signature), ret_signature),
73 | '\n=======================================\n']))
74 | raise NotImplementedError('The method {} is not implemented'.format(key))
75 |
76 | return py_method(*args)
77 |
78 |
79 | cdef jobject py_invoke0(JNIEnv *j_env, jobject j_this, jobject j_proxy, jobject
80 | j_method, jobjectArray args) except * with gil:
81 |
82 | from .reflect import get_signature, Method
83 | cdef jfieldID ptrField
84 | cdef jlong jptr
85 | cdef object py_obj
86 | cdef JavaClass method
87 | cdef jobject j_arg
88 |
89 | # get the python object
90 | ptrField = j_env[0].GetFieldID(j_env,
91 | j_env[0].GetObjectClass(j_env, j_this), "ptr", "J")
92 | jptr = j_env[0].GetLongField(j_env, j_this, ptrField)
93 | py_obj = jptr
94 |
95 | # extract the method information
96 | method = Method(noinstance=True)
97 | method.instanciate_from(create_local_ref(j_env, j_method))
98 | ret_signature = get_signature(method.getReturnType())
99 | args_signature = [get_signature(x) for x in method.getParameterTypes()]
100 |
101 | # convert java argument to python object
102 | # native java type are given with java.lang.*, even if the signature say
103 | # it's a native type.
104 | py_args = []
105 | convert_signature = {
106 | 'Z': 'Ljava/lang/Boolean;',
107 | 'B': 'Ljava/lang/Byte;',
108 | 'C': 'Ljava/lang/Character;',
109 | 'S': 'Ljava/lang/Short;',
110 | 'I': 'Ljava/lang/Integer;',
111 | 'J': 'Ljava/lang/Long;',
112 | 'F': 'Ljava/lang/Float;',
113 | 'D': 'Ljava/lang/Double;'}
114 |
115 | for index, arg_signature in enumerate(args_signature):
116 | arg_signature = convert_signature.get(arg_signature, arg_signature)
117 | j_arg = j_env[0].GetObjectArrayElement(j_env, args, index)
118 | py_arg = convert_jobject_to_python(j_env, arg_signature, j_arg)
119 | j_env[0].DeleteLocalRef(j_env, j_arg)
120 | py_args.append(py_arg)
121 |
122 | # really invoke the python method
123 | name = method.getName()
124 | ret = py_obj.invoke(method, *py_args)
125 |
126 | # convert back to the return type
127 | # use the populate_args(), but in the reverse way :)
128 | t = ret_signature[:1]
129 |
130 | # did python returned a "native" type ?
131 | jtype = None
132 |
133 | if ret_signature == 'Ljava/lang/Object;':
134 | # generic object, try to manually convert it
135 | tp = type(ret)
136 | if tp == int:
137 | jtype = 'J'
138 | elif tp == float:
139 | jtype = 'D'
140 | elif tp == bool:
141 | jtype = 'Z'
142 | elif len(ret_signature) == 1:
143 | jtype = ret_signature
144 |
145 | try:
146 | return convert_python_to_jobject(j_env, jtype or ret_signature, ret)
147 | except Exception:
148 | traceback.print_exc()
149 |
150 |
151 | cdef jobject invoke0(JNIEnv *j_env, jobject j_this, jobject j_proxy, jobject
152 | j_method, jobjectArray args) with gil:
153 | try:
154 | return py_invoke0(j_env, j_this, j_proxy, j_method, args)
155 | except Exception:
156 | traceback.print_exc()
157 | return NULL
158 |
159 | # now we need to create a proxy and pass it an invocation handler
160 | cdef create_proxy_instance(JNIEnv *j_env, py_obj, j_interfaces, javacontext):
161 | from .reflect import autoclass
162 | Proxy = autoclass('java.lang.reflect.Proxy')
163 | NativeInvocationHandler = autoclass('org.jnius.NativeInvocationHandler')
164 |
165 | # convert strings to Class
166 | j_interfaces = [find_javaclass(x) for x in j_interfaces]
167 |
168 | cdef JavaClass nih = NativeInvocationHandler(py_obj)
169 | cdef JNINativeMethod invoke_methods[1]
170 | invoke_methods[0].name = 'invoke0'
171 | invoke_methods[0].signature = '(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;'
172 | invoke_methods[0].fnPtr = &invoke0
173 | j_env[0].RegisterNatives(j_env, nih.j_cls, invoke_methods, 1)
174 |
175 | # create the proxy and pass it the invocation handler
176 | cdef JavaClass j_obj
177 | if javacontext == 'app':
178 | Thread = autoclass('java.lang.Thread')
179 | classLoader = Thread.currentThread().getContextClassLoader()
180 | j_obj = Proxy.newProxyInstance(
181 | classLoader, j_interfaces, nih)
182 |
183 | elif javacontext == 'system':
184 | ClassLoader = autoclass('java.lang.ClassLoader')
185 | classLoader = ClassLoader.getSystemClassLoader()
186 | j_obj = Proxy.newProxyInstance(
187 | classLoader, j_interfaces, nih)
188 |
189 | else:
190 | raise Exception(
191 | 'Invalid __javacontext__ {}, must be app or system.'.format(
192 | javacontext))
193 |
194 | return j_obj
195 |
--------------------------------------------------------------------------------
/jnius/signatures.py:
--------------------------------------------------------------------------------
1 | '''
2 | signatures.py
3 | =============
4 |
5 | A handy API for writing JNI signatures easily
6 |
7 | Author: chrisjrn
8 |
9 | This module aims to provide a more human-friendly API for
10 | wiring up Java proxy methods in PyJnius.
11 |
12 | You can use the signature function to produce JNI method
13 | signautures for methods; passing PyJnius JavaClass classes
14 | as return or argument types; provided here are annotations
15 | representing Java's primitive and array times.
16 |
17 | Methods can return just a standard primitive type:
18 |
19 | >>> signature(jint, ())
20 | '()I'
21 |
22 | >>> s.signature(jvoid, [jint])
23 | '(I)V'
24 |
25 | Or you can use autoclass proxies to specify Java classes
26 | for return types.
27 |
28 | >>> from jnius import autoclass
29 | >>> String = autoclass("java.lang.String")
30 | >>> signature(String, ())
31 | '()Ljava/lang/String;'
32 |
33 | '''
34 |
35 | __version__ = '0.0.1'
36 |
37 | from . import JavaClass
38 | from . import java_method
39 |
40 |
41 | ''' Type specifiers for primitives '''
42 |
43 |
44 | class _JavaSignaturePrimitive(object):
45 | _spec = ""
46 |
47 |
48 | def _MakeSignaturePrimitive(name, spec):
49 | class __Primitive(_JavaSignaturePrimitive):
50 | ''' PyJnius signature for Java %s type ''' % name
51 | _name = name
52 | _spec = spec
53 | __Primitive.__name__ = "j" + name
54 |
55 | return __Primitive
56 |
57 |
58 | jboolean = _MakeSignaturePrimitive("boolean", "Z")
59 | jbyte = _MakeSignaturePrimitive("byte", "B")
60 | jchar = _MakeSignaturePrimitive("char", "C")
61 | jdouble = _MakeSignaturePrimitive("double", "D")
62 | jfloat = _MakeSignaturePrimitive("float", "F")
63 | jint = _MakeSignaturePrimitive("int", "I")
64 | jlong = _MakeSignaturePrimitive("long", "J")
65 | jshort = _MakeSignaturePrimitive("short", "S")
66 | jvoid = _MakeSignaturePrimitive("void", "V")
67 |
68 |
69 | def JArray(of_type):
70 | ''' Signature helper for identifying arrays of a given object or
71 | primitive type. '''
72 |
73 | spec = "[" + _jni_type_spec(of_type)
74 | return _MakeSignaturePrimitive("array", spec)
75 |
76 |
77 | def with_signature(returns, takes):
78 | ''' Alternative version of @java_method that takes JavaClass
79 | objects to produce the method signature. '''
80 |
81 | sig = signature(returns, takes)
82 | return java_method(sig)
83 |
84 |
85 | def signature(returns, takes):
86 | ''' Produces a JNI method signature, taking the provided arguments
87 | and returning the given return type. '''
88 |
89 | out_takes = []
90 | for arg in takes:
91 | out_takes.append(_jni_type_spec(arg))
92 |
93 | return "(" + "".join(out_takes) + ")" + _jni_type_spec(returns)
94 |
95 |
96 | def _jni_type_spec(jclass):
97 | ''' Produces a JNI type specification string for the given argument.
98 | If the argument is a jnius.JavaClass, it produces the JNI type spec
99 | for the class. Signature primitives return their stored type spec.
100 | '''
101 |
102 | if issubclass(jclass, JavaClass):
103 | return "L" + jclass.__javaclass__ + ";"
104 | elif issubclass(jclass, _JavaSignaturePrimitive):
105 | return jclass._spec
106 |
--------------------------------------------------------------------------------
/jnius/src/org/jnius/NativeInvocationHandler.java:
--------------------------------------------------------------------------------
1 | package org.jnius;
2 | import java.lang.reflect.InvocationHandler;
3 | import java.lang.reflect.Method;
4 |
5 | public class NativeInvocationHandler implements InvocationHandler {
6 | static boolean DEBUG = false;
7 | private long ptr;
8 |
9 | public NativeInvocationHandler(long ptr) {
10 | this.ptr = ptr;
11 | }
12 |
13 | public Object invoke(Object proxy, Method method, Object[] args) {
14 | if ( DEBUG ) {
15 | // don't call it, or recursive lookup/proxy will go!
16 | //System.out.print(proxy);
17 | //System.out.print(", ");
18 | String message = "+ java:invoke(, " + method + ", " + args;
19 | System.out.print(message);
20 | System.out.println(")");
21 | System.out.flush();
22 | }
23 |
24 | Object ret = invoke0(proxy, method, args);
25 |
26 | if ( DEBUG ) {
27 | System.out.print("+ java:invoke returned: ");
28 | System.out.println(ret);
29 | }
30 |
31 | return ret;
32 | }
33 |
34 | public long getPythonObjectPointer() {
35 | return ptr;
36 | }
37 |
38 | native Object invoke0(Object proxy, Method method, Object[] args);
39 | }
40 |
--------------------------------------------------------------------------------
/jnius_config.py:
--------------------------------------------------------------------------------
1 | __all__ = ('set_options', 'add_options', 'get_options',
2 | 'set_classpath', 'add_classpath', 'get_classpath',
3 | 'expand_classpath')
4 |
5 | import platform
6 | if platform.system() == 'Windows':
7 | split_char = ';'
8 | else:
9 | split_char = ':'
10 |
11 | vm_running = False
12 | vm_started_at = None
13 | options = []
14 | classpath = None
15 |
16 |
17 | def check_vm_running():
18 | """Raises a ValueError if the VM is already running."""
19 | if vm_running:
20 | raise ValueError("VM is already running, can't set classpath/options; VM started at" + vm_started_at)
21 |
22 |
23 | def set_options(*opts):
24 | """Sets the list of options to the JVM. Removes any previously set options."""
25 | check_vm_running()
26 | global options
27 | options = list(opts)
28 |
29 |
30 | def add_options(*opts):
31 | """Appends options to the list of VM options."""
32 | check_vm_running()
33 | global options
34 | options.extend(opts)
35 |
36 |
37 | def get_options():
38 | """Retrieves the current list of VM options."""
39 | global options
40 | return list(options)
41 |
42 |
43 | def set_classpath(*path):
44 | """
45 | Sets the classpath for the JVM to use. Replaces any existing classpath, overriding the CLASSPATH environment variable.
46 | """
47 | check_vm_running()
48 | global classpath
49 | classpath = list(path)
50 |
51 |
52 | def add_classpath(*path):
53 | """
54 | Appends items to the classpath for the JVM to use.
55 | Replaces any existing classpath, overriding the CLASSPATH environment variable.
56 | """
57 | check_vm_running()
58 | global classpath
59 | if classpath is None:
60 | classpath = list(path)
61 | else:
62 | classpath.extend(path)
63 |
64 |
65 | def get_classpath():
66 | "Retrieves the classpath the JVM will use."
67 | from os import environ
68 | from os.path import realpath
69 | import sys
70 | global classpath
71 |
72 | # add a path to java classes packaged with jnius
73 | if sys.version_info >= (3, 9):
74 | from contextlib import ExitStack
75 | import importlib.resources
76 | import atexit
77 |
78 | # see https://importlib-resources.readthedocs.io/en/latest/migration.html#pkg-resources-resource-filename
79 | file_manager = ExitStack()
80 | atexit.register(file_manager.close)
81 | # importlib.resources.files is only available from Python 3.9
82 | # use https://github.com/python/importlib_resources/issues/60 not __name__ as jnius_config.py is not a package
83 | resource_path = importlib.resources.files('jnius') / 'src'
84 | return_classpath = [ str(resource_path) ]
85 | file_manager.enter_context(importlib.resources.as_file(resource_path))
86 | else:
87 | from pkg_resources import resource_filename
88 | return_classpath = [realpath(resource_filename(__name__, 'jnius/src'))]
89 |
90 |
91 | if classpath is not None:
92 | return_classpath = classpath + return_classpath
93 |
94 | elif 'CLASSPATH' in environ:
95 | return_classpath = environ['CLASSPATH'].split(split_char) + return_classpath
96 |
97 | else:
98 | return_classpath = [realpath('.')] + return_classpath
99 |
100 | return return_classpath
101 |
102 |
103 | def expand_classpath():
104 | from glob import glob
105 | paths = []
106 | # deal with wildcards
107 | for path in get_classpath():
108 | if not path.endswith('*'):
109 | paths.append(path)
110 | else:
111 | paths.extend(glob(path + '.[Jj][Aa][Rr]'))
112 | return split_char.join(paths)
113 |
--------------------------------------------------------------------------------
/main.workflow:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = [
3 | "setuptools>=58.0.0",
4 | "wheel",
5 | "Cython"
6 | ]
7 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": [
4 | "config:recommended"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [options.extras_require]
2 | dev =
3 | pytest
4 | pytest-cov
5 | pycodestyle
6 | ci =
7 | coveralls
8 | pytest-rerunfailures
9 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | '''
2 | Setup.py for creating a binary distribution.
3 | '''
4 |
5 | from os import environ
6 | from os.path import dirname, join
7 | import subprocess
8 | import sys
9 |
10 | from setup_sdist import SETUP_KWARGS
11 | from setuptools import setup, Extension
12 | from setuptools.command.build_ext import build_ext
13 |
14 |
15 | # XXX hack to be able to import jnius.env withough having build
16 | # jnius.jnius yet, better solution welcome
17 | syspath = sys.path[:]
18 | sys.path.insert(0, 'jnius')
19 | from env import get_java_setup
20 | sys.path = syspath
21 |
22 | def getenv(key):
23 | '''Get value from environment and decode it.'''
24 | val = environ.get(key)
25 | if val is not None:
26 | try:
27 | return val.decode()
28 | except AttributeError:
29 | return val
30 | return val
31 |
32 |
33 | PYX_FILES = [
34 | 'jnius.pyx',
35 | ]
36 | PXI_FILES = [
37 | 'jnius_compat.pxi',
38 | 'jnius_conversion.pxi',
39 | 'jnius_export_class.pxi',
40 | 'jnius_export_func.pxi',
41 | 'jnius_jvm_android.pxi',
42 | 'jnius_jvm_desktop.pxi',
43 | 'jnius_jvm_dlopen.pxi',
44 | 'jnius_localref.pxi',
45 | 'jnius_nativetypes3.pxi',
46 | 'jnius_proxy.pxi',
47 | 'jnius.pyx',
48 | 'jnius_utils.pxi'
49 | ]
50 |
51 | EXTRA_LINK_ARGS = []
52 |
53 | # detect Python for android
54 | PLATFORM = sys.platform
55 | NDKPLATFORM = getenv('NDKPLATFORM')
56 | if NDKPLATFORM is not None and getenv('LIBLINK'):
57 | PLATFORM = 'android'
58 |
59 | # detect platform
60 | if PLATFORM == 'android':
61 | PYX_FILES = [fn[:-3] + 'c' for fn in PYX_FILES]
62 |
63 | JAVA=get_java_setup(PLATFORM)
64 |
65 | assert JAVA.is_jdk(), "You need a JDK, we only found a JRE. Try setting JAVA_HOME"
66 |
67 |
68 | def compile_native_invocation_handler(java):
69 | '''Find javac and compile NativeInvocationHandler.java.'''
70 | javac = java.get_javac()
71 | source_level = '8'
72 | try:
73 | subprocess.check_call([
74 | javac, '-target', source_level, '-source', source_level,
75 | join('jnius', 'src', 'org', 'jnius', 'NativeInvocationHandler.java')
76 | ])
77 | except FileNotFoundError:
78 | subprocess.check_call([
79 | javac.replace('"', ''), '-target', source_level, '-source', source_level,
80 | join('jnius', 'src', 'org', 'jnius', 'NativeInvocationHandler.java')
81 | ])
82 |
83 |
84 | compile_native_invocation_handler(JAVA)
85 |
86 |
87 | # generate the config.pxi
88 | with open(join(dirname(__file__), 'jnius', 'config.pxi'), 'w') as fd:
89 | if PLATFORM == 'android':
90 | cython3 = environ.get('ANDROID_PYJNIUS_CYTHON_3', '0') == '1'
91 | else:
92 | import Cython
93 | cython3 = Cython.__version__.startswith('3.')
94 | fd.write('DEF JNIUS_PLATFORM = {0!r}\n\n'.format(PLATFORM))
95 | # record the Cython version, to address #669
96 | fd.write(f'DEF JNIUS_CYTHON_3 = {cython3}')
97 |
98 | # pop setup.py from included files in the installed package
99 | SETUP_KWARGS['py_modules'].remove('setup')
100 |
101 | ext_modules = [
102 | Extension(
103 | 'jnius',
104 | [join('jnius', x) for x in PYX_FILES],
105 | depends=[join('jnius', x) for x in PXI_FILES],
106 | libraries=JAVA.get_libraries(),
107 | library_dirs=JAVA.get_library_dirs(),
108 | include_dirs=JAVA.get_include_dirs(),
109 | extra_link_args=EXTRA_LINK_ARGS,
110 | )
111 | ]
112 |
113 | for ext_mod in ext_modules:
114 | ext_mod.cython_directives = {'language_level': 3}
115 |
116 |
117 | # create the extension
118 | setup(
119 | cmdclass={'build_ext': build_ext},
120 | ext_modules=ext_modules,
121 | **SETUP_KWARGS
122 | )
123 |
--------------------------------------------------------------------------------
/setup_sdist.py:
--------------------------------------------------------------------------------
1 | '''
2 | Setup.py only for creating a source distributions.
3 |
4 | This file holds all the common setup.py keyword arguments between the source
5 | distribution and the ordinary setup.py for binary distribution. Running this
6 | instead of the default setup.py will create a GitHub-like archive with setup.py
7 | meant for installing via pip.
8 | '''
9 | from io import open
10 |
11 | # pylint: disable=import-error,no-name-in-module
12 | from setuptools import setup
13 | from os.path import join
14 |
15 | with open("README.md", encoding='utf8') as f:
16 | README = f.read()
17 |
18 |
19 | with open(join('jnius', '__init__.py')) as fd:
20 | VERSION = [
21 | x for x in fd.readlines()
22 | if x.startswith('__version__')
23 | ][0].split("'")[-2]
24 |
25 |
26 | SETUP_KWARGS = {
27 | 'name': 'pyjnius',
28 | 'version': VERSION,
29 | 'url': "https://github.com/kivy/pyjnius",
30 | 'project_urls': {
31 | 'Website': "https://kivy.org",
32 | 'Documentation': "https://pyjnius.readthedocs.io",
33 | 'Source': "https://github.com/kivy/pyjnius",
34 | 'Bug Reports': "https://github.com/kivy/pyjnius/issues",
35 | },
36 | 'packages': ['jnius'],
37 | 'py_modules': ['jnius_config', 'setup', 'setup_sdist', 'jnius.env'],
38 | 'ext_package': 'jnius',
39 | 'package_data': {
40 | 'jnius': ['src/org/jnius/*'],
41 | },
42 | 'long_description_content_type': 'text/markdown',
43 | 'long_description': README,
44 | 'author': 'Kivy Team and other contributors',
45 | 'author_email': 'kivy-dev@googlegroups.com',
46 | 'description':
47 | "A Python library for accessing access Java classes as using the "
48 | "Java Native Interface (JNI).",
49 | 'keywords': 'Java JNI Android',
50 | 'classifiers': [
51 | 'Development Status :: 5 - Production/Stable',
52 | 'Intended Audience :: Developers',
53 | 'License :: OSI Approved :: MIT License',
54 | 'Natural Language :: English',
55 | 'Operating System :: MacOS',
56 | 'Operating System :: Microsoft :: Windows',
57 | 'Operating System :: POSIX :: Linux',
58 | 'Operating System :: Android',
59 | 'Programming Language :: Python :: 3.8',
60 | 'Programming Language :: Python :: 3.9',
61 | 'Programming Language :: Python :: 3.10',
62 | 'Programming Language :: Python :: 3.11',
63 | 'Programming Language :: Python :: 3.12',
64 | 'Topic :: Software Development :: Libraries :: Application Frameworks'
65 | ]
66 | }
67 |
68 | if __name__ == '__main__':
69 | setup(**SETUP_KWARGS)
70 |
--------------------------------------------------------------------------------
/tests/android/testhardware/main.py:
--------------------------------------------------------------------------------
1 | from time import sleep
2 | from jnius import autoclass
3 |
4 | print '-- test hardware start!'
5 |
6 | Hardware = autoclass('org.renpy.android.Hardware')
7 | print 'DPI is', Hardware.getDPI()
8 |
9 | Hardware.accelerometerEnable(True)
10 | for x in xrange(20):
11 | print Hardware.accelerometerReading()
12 | sleep(.1)
13 |
14 | print '-- test hardware done!'
15 |
--------------------------------------------------------------------------------
/tests/java-src/org/jnius/BasicsTest.java:
--------------------------------------------------------------------------------
1 | package org.jnius;
2 |
3 | import java.lang.String;
4 |
5 | public class BasicsTest {
6 | static public boolean methodStaticZ() { return true; };
7 | static public byte methodStaticB() { return 127; };
8 | static public char methodStaticC() { return 'k'; };
9 | static public short methodStaticS() { return 32767; };
10 | static public int methodStaticI() { return 2147483467; };
11 | static public long methodStaticJ() { return 9223372036854775807L; };
12 | static public float methodStaticF() { return 1.23456789f; };
13 | static public double methodStaticD() { return 1.23456789; };
14 | static public String methodStaticString() { return new String("hello \uD83C\uDF0E!"); }
15 |
16 | public boolean methodZ() { return true; };
17 | public byte methodB() { return 127; };
18 | public char methodC() { return 'k'; };
19 | public short methodS() { return 32767; };
20 | public int methodI() { return 2147483467; };
21 | public long methodJ() { return 9223372036854775807L; };
22 | public float methodF() { return 1.23456789f; };
23 | public double methodD() { return 1.23456789; };
24 | public String methodString() { return new String("hello \uD83C\uDF0E!"); }
25 | public void methodException(int depth) throws IllegalArgumentException {
26 | if (depth == 0) throw new IllegalArgumentException("hello \uD83C\uDF0E!");
27 | else methodException(depth -1);
28 | }
29 | public void methodExceptionChained() throws IllegalArgumentException {
30 | try {
31 | methodException(5);
32 | } catch (IllegalArgumentException e) {
33 | throw new IllegalArgumentException("helloworld2", e);
34 | }
35 | }
36 | public boolean getDisabled() { return true; };
37 | public boolean isEnabled() { return !this.getDisabled(); };
38 |
39 | static public boolean fieldStaticZ = true;
40 | static public byte fieldStaticB = 127;
41 | static public char fieldStaticC = 'k';
42 | static public short fieldStaticS = 32767;
43 | static public int fieldStaticI = 2147483467;
44 | static public long fieldStaticJ = 9223372036854775807L;
45 | static public float fieldStaticF = 1.23456789f;
46 | static public double fieldStaticD = 1.23456789;
47 | static public String fieldStaticString = new String("hello \uD83C\uDF0E!");
48 |
49 | public boolean fieldZ = true;
50 | public byte fieldB = 127;
51 | public char fieldC = 'k';
52 | public short fieldS = 32767;
53 | public int fieldI = 2147483467;
54 | public long fieldJ = 9223372036854775807L;
55 | public float fieldF = 1.23456789f;
56 | public double fieldD = 1.23456789;
57 | public String fieldString = new String("hello \uD83C\uDF0E!");
58 |
59 | public boolean fieldSetZ;
60 | public byte fieldSetB;
61 | public char fieldSetC;
62 | public short fieldSetS;
63 | public int fieldSetI;
64 | public long fieldSetJ;
65 | public float fieldSetF;
66 | public double fieldSetD;
67 | public String fieldSetString;
68 |
69 | // Floating-point comparison epsilon
70 | private final static double EPSILON = 1E-6;
71 |
72 | public BasicsTest() {}
73 | public BasicsTest(byte fieldBVal) {
74 | fieldB = fieldBVal;
75 | }
76 |
77 | public boolean[] methodArrayZ() {
78 | boolean[] x = new boolean[3];
79 | x[0] = x[1] = x[2] = true;
80 | return x;
81 | };
82 | public byte[] methodArrayB() {
83 | byte[] x = new byte[3];
84 | x[0] = x[1] = x[2] = 127;
85 | return x;
86 | };
87 | public char[] methodArrayC() {
88 | char[] x = new char[3];
89 | x[0] = x[1] = x[2] = 'k';
90 | return x;
91 | };
92 | public short[] methodArrayS() {
93 | short[] x = new short[3];
94 | x[0] = x[1] = x[2] = 32767;
95 | return x;
96 | };
97 | public int[] methodArrayI() {
98 | int[] x = new int[3];
99 | x[0] = x[1] = x[2] = 2147483467;
100 | return x;
101 | };
102 | public long[] methodArrayJ() {
103 | long[] x = new long[3];
104 | x[0] = x[1] = x[2] = 9223372036854775807L;
105 | return x;
106 | };
107 | public float[] methodArrayF() {
108 | float[] x = new float[3];
109 | x[0] = x[1] = x[2] = 1.23456789f;
110 | return x;
111 | };
112 | public double[] methodArrayD() {
113 | double[] x = new double[3];
114 | x[0] = x[1] = x[2] = 1.23456789;
115 | return x;
116 | };
117 | public String[] methodArrayString() {
118 | String[] x = new String[3];
119 | x[0] = x[1] = x[2] = new String("hello \uD83C\uDF0E!");
120 | return x;
121 | };
122 |
123 |
124 | public boolean methodParamsZBCSIJFD(boolean x1, byte x2, char x3, short x4,
125 | int x5, long x6, float x7, double x8) {
126 | return (x1 == true && x2 == 127 && x3 == 'k' && x4 == 32767 &&
127 | x5 == 2147483467 && x6 == 9223372036854775807L &&
128 | (Math.abs(x7 - 1.23456789f) < EPSILON) &&
129 | (Math.abs(x8 - 1.23456789) < EPSILON));
130 | }
131 |
132 | public boolean methodParamsString(String s) {
133 | return (s.equals("hello \uD83C\uDF0E!"));
134 | }
135 |
136 | public boolean methodParamsArrayI(int[] x) {
137 | if (x.length != 3)
138 | return false;
139 | return (x[0] == 1 && x[1] == 2 && x[2] == 3);
140 | }
141 |
142 | public boolean methodParamsArrayString(String[] x) {
143 | if (x.length != 2)
144 | return false;
145 | return (x[0].equals("hello") && x[1].equals("\uD83C\uDF0E"));
146 | }
147 |
148 | public boolean methodParamsObject(Object x) {
149 | return true;
150 | }
151 |
152 | public Object methodReturnStrings() {
153 | String[] hello_world = new String[2];
154 | hello_world[0] = "Hello";
155 | hello_world[1] = "\uD83C\uDF0E";
156 | return hello_world;
157 | }
158 |
159 | public Object methodReturnIntegers() {
160 | int[] integers = new int[2];
161 | integers[0] = 1;
162 | integers[1] = 2;
163 | return integers;
164 | }
165 |
166 | public boolean methodParamsArrayByte(byte[] x) {
167 | if (x.length != 3)
168 | return false;
169 | return (x[0] == 127 && x[1] == 127 && x[2] == 127);
170 | }
171 |
172 | public void fillByteArray(byte[] x) {
173 | if (x.length != 3)
174 | return;
175 | x[0] = 127;
176 | x[1] = 1;
177 | x[2] = -127;
178 | }
179 |
180 | public byte[] methodReturnEmptyByteArray() {
181 | return new byte[0];
182 | }
183 |
184 | public boolean testFieldSetZ() {
185 | return (fieldSetZ == true);
186 | }
187 |
188 | public boolean testFieldSetB() {
189 | return (fieldSetB == 127);
190 | }
191 |
192 | public boolean testFieldSetC() {
193 | return (fieldSetC == 'k');
194 | }
195 |
196 | public boolean testFieldSetS() {
197 | return (fieldSetS == 32767);
198 | }
199 |
200 | public boolean testFieldSetI() {
201 | return (fieldSetI == 2147483467);
202 | }
203 |
204 | public boolean testFieldSetJ() {
205 | return (fieldSetJ == 9223372036854775807L);
206 | }
207 |
208 | public boolean testFieldSetF() {
209 | return (Math.abs(fieldSetF - 1.23456789f) < EPSILON);
210 | }
211 |
212 | public boolean testFieldSetD() {
213 | return (Math.abs(fieldSetD - 1.23456789) < EPSILON);
214 | }
215 | }
216 |
--------------------------------------------------------------------------------
/tests/java-src/org/jnius/CharsAndStrings.java:
--------------------------------------------------------------------------------
1 | package org.jnius;
2 |
3 | import java.lang.String;
4 |
5 | public class CharsAndStrings {
6 |
7 | public char testChar1;
8 | public char testChar2;
9 | public char testChar3;
10 | public String testString1;
11 | public String testString2;
12 | public String testString3;
13 |
14 | static public char testStaticChar1 = 'a';
15 | static public char testStaticChar2 = 'ä';
16 | static public char testStaticChar3 = '☺';
17 | static public String testStaticString1 = "hello world";
18 | static public String testStaticString2 = "umlauts: äöü";
19 | static public String testStaticString3 = "happy face: ☺";
20 |
21 | public char[] testCharArray1;
22 | public char[] testCharArray2;
23 | static public char[] testStaticCharArray1 = new char[]{'a', 'b', 'c'};
24 | static public char[] testStaticCharArray2 = new char[]{'a', 'ä', '☺'};
25 | static public String testStringDefNull = null;
26 | static public int testInt = 0;
27 |
28 | public CharsAndStrings() {
29 | this.testChar1 = 'a';
30 | this.testChar2 = 'ä';
31 | this.testChar3 = '☺';
32 |
33 | this.testString1 = "hello world";
34 | this.testString2 = "umlauts: äöü";
35 | this.testString3 = "happy face: ☺";
36 |
37 | testCharArray1 = new char[]{'a', 'b', 'c'};
38 | testCharArray2 = new char[]{'a', 'ä', '☺'};
39 | }
40 |
41 | public char testChar(int i, char testChar) {
42 | if (i == 1) {
43 | assert this.testChar1 == testChar;
44 | return this.testChar1;
45 | } else if (i == 2) {
46 | assert this.testChar2 == testChar;
47 | return this.testChar2;
48 | } else {
49 | assert this.testChar3 == testChar;
50 | return this.testChar3;
51 | }
52 | }
53 |
54 | static public char testStaticChar(int i, char testChar) {
55 | if (i == 1) {
56 | assert CharsAndStrings.testStaticChar1 == testChar;
57 | return CharsAndStrings.testStaticChar1;
58 | } else if (i == 2) {
59 | assert CharsAndStrings.testStaticChar2 == testChar;
60 | return CharsAndStrings.testStaticChar2;
61 | } else {
62 | assert CharsAndStrings.testStaticChar3 == testChar;
63 | return CharsAndStrings.testStaticChar3;
64 | }
65 | }
66 |
67 | public String testString(int i, String testString) {
68 | if (i == 1) {
69 | assert this.testString1.equals(testString);
70 | return this.testString1;
71 | } else if (i == 2) {
72 | assert this.testString2.equals(testString);
73 | return this.testString2;
74 | } else {
75 | assert this.testString3.equals(testString);
76 | return this.testString3;
77 | }
78 | }
79 |
80 | static public String testStaticString(int i, String testString) {
81 | if (i == 1) {
82 | assert CharsAndStrings.testStaticString1.equals(testString);
83 | return CharsAndStrings.testStaticString1;
84 | } else if (i == 2) {
85 | assert CharsAndStrings.testStaticString2.equals(testString);
86 | return CharsAndStrings.testStaticString2;
87 | } else {
88 | assert CharsAndStrings.testStaticString3.equals(testString);
89 | return CharsAndStrings.testStaticString3;
90 | }
91 | }
92 |
93 | public char[] testCharArray(int i) {
94 | if (i == 1) {
95 | return testCharArray1;
96 | } else {
97 | return testCharArray2;
98 | }
99 | }
100 |
101 | static public char[] testStaticCharArray(int i) {
102 | if (i == 1) {
103 | return testStaticCharArray1;
104 | } else {
105 | return testStaticCharArray2;
106 | }
107 | }
108 |
109 | static public void setString(String ignore, String value) {
110 | testStringDefNull = value;
111 | }
112 |
113 | static public void setInt(String ignore, int value) {
114 | testInt = value;
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/tests/java-src/org/jnius/Child.java:
--------------------------------------------------------------------------------
1 | package org.jnius;
2 |
3 | import org.jnius.Parent;
4 |
5 | public class Child extends Parent {
6 |
7 | public int CHILD_FIELD = 1;
8 |
9 | public int doCall(int child) {
10 | return 1;
11 | }
12 |
13 | static public Child newInstance(){
14 | return new Child();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tests/java-src/org/jnius/ChildVisibilityTest.java:
--------------------------------------------------------------------------------
1 | package org.jnius;
2 |
3 | import java.lang.String;
4 |
5 | public class ChildVisibilityTest extends VisibilityTest {
6 | public String fieldChildPublic = "ChildPublic";
7 | String fieldChildPackageProtected = "ChildPackageProtected";
8 | protected String fieldChildProtected = "ChildProtected";
9 | private String fieldChildPrivate = "ChildPrivate";
10 |
11 | static public String fieldChildStaticPublic = "ChildStaticPublic";
12 | static String fieldChildStaticPackageProtected = "ChildStaticPackageProtected";
13 | static protected String fieldChildStaticProtected = "ChildStaticProtected";
14 | static private String fieldChildStaticPrivate = "ChildStaticPrivate";
15 |
16 | public String methodChildPublic() {
17 | return fieldChildPublic;
18 | }
19 |
20 | String methodChildPackageProtected() {
21 | return fieldChildPackageProtected;
22 | }
23 |
24 | protected String methodChildProtected() {
25 | return fieldChildProtected;
26 | }
27 |
28 | private String methodChildPrivate() {
29 | return fieldChildPrivate;
30 | }
31 |
32 | protected boolean methodMultiArgs(boolean a, boolean b) {
33 | return a & !b;
34 | }
35 |
36 | private boolean methodMultiArgs(boolean a, boolean b, boolean c) {
37 | return a & !b & c;
38 | }
39 |
40 | // dummy method to avoid warning about unused methods
41 | public String methodChildDummy() {
42 | this.methodMultiArgs(true, true, false);
43 | return this.methodChildPrivate();
44 | }
45 |
46 | static public String methodChildStaticPublic() {
47 | return fieldChildStaticPublic;
48 | }
49 |
50 | static String methodChildStaticPackageProtected() {
51 | return fieldChildStaticPackageProtected;
52 | }
53 |
54 | static protected String methodChildStaticProtected() {
55 | return fieldChildStaticProtected;
56 | }
57 |
58 | static private String methodChildStaticPrivate() {
59 | return fieldChildStaticPrivate;
60 | }
61 |
62 | static protected boolean methodStaticMultiArgs(boolean a, boolean b) {
63 | return a & !b;
64 | }
65 |
66 | static private boolean methodStaticMultiArgs(boolean a, boolean b, boolean c) {
67 | return a & !b & c;
68 | }
69 |
70 | // dummy method to avoid warning about unused methods
71 | static public String methodChildStaticDummy() {
72 | ChildVisibilityTest.methodStaticMultiArgs(true, true, true);
73 | return ChildVisibilityTest.methodChildStaticPrivate();
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/tests/java-src/org/jnius/ClassArgument.java:
--------------------------------------------------------------------------------
1 | package org.jnius;
2 |
3 |
4 | public class ClassArgument {
5 | public static String getName(Class klass) {
6 | return klass.toString();
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/tests/java-src/org/jnius/CloseableClass.java:
--------------------------------------------------------------------------------
1 | package org.jnius;
2 |
3 | import java.io.Closeable;
4 |
5 | public class CloseableClass implements Closeable{
6 | public static boolean open = true;
7 |
8 | public CloseableClass() {
9 | open = true;
10 | }
11 |
12 | public void close() {
13 | open = false;
14 | }
15 | }
--------------------------------------------------------------------------------
/tests/java-src/org/jnius/ConstructorTest.java:
--------------------------------------------------------------------------------
1 | package org.jnius;
2 | import java.lang.Character;
3 |
4 |
5 | public class ConstructorTest {
6 | public int ret;
7 |
8 | public ConstructorTest() {
9 | ret = 753;
10 | }
11 |
12 | public ConstructorTest(int cret) {
13 | ret = cret;
14 | }
15 |
16 | public ConstructorTest(char charet) {
17 | ret = (int) charet;
18 | }
19 |
20 | public ConstructorTest(int cret, char charet) {
21 | ret = cret + (int) charet;
22 | }
23 |
24 | public ConstructorTest(Object DO_NOT_CALL) {
25 | throw new Error();
26 | }
27 |
28 | public ConstructorTest(java.io.OutputStream os) {
29 | ret = 42;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/tests/java-src/org/jnius/HelloWorld.java:
--------------------------------------------------------------------------------
1 | package org.jnius;
2 |
3 | public class HelloWorld {
4 | public String hello() {
5 | return new String("world");
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/tests/java-src/org/jnius/InterfaceWithPublicEnum.java:
--------------------------------------------------------------------------------
1 | package org.jnius;
2 |
3 |
4 | public interface InterfaceWithPublicEnum {
5 |
6 | public enum ATTITUDE {
7 | GOOD, BAD, UGLY,
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/tests/java-src/org/jnius/MultipleDimensions.java:
--------------------------------------------------------------------------------
1 | package org.jnius;
2 |
3 | public class MultipleDimensions {
4 | public static boolean methodParamsMatrixI(int[][] x) {
5 | if (x.length != 3 || x[0].length != 3)
6 | return false;
7 | return (x[0][0] == 1 && x[0][1] == 2 && x[1][2] == 6);
8 | }
9 | public static int[][] methodReturnMatrixI() {
10 | int[][] matrix = {{1,2,3},
11 | {4,5,6},
12 | {7,8,9}};
13 | return matrix;
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/tests/java-src/org/jnius/MultipleMethods.java:
--------------------------------------------------------------------------------
1 | package org.jnius;
2 |
3 | public class MultipleMethods {
4 |
5 | public static String resolve() {
6 | return "resolved no args";
7 | }
8 |
9 | public static String resolve(String i) {
10 | return "resolved one arg";
11 | }
12 |
13 | public static String resolve(String i, String j) {
14 | return "resolved two args";
15 | }
16 |
17 | public static String resolve(String i, String j, int k) {
18 | return "resolved two string and an integer";
19 | }
20 |
21 | public static String resolve(String i, String j, int k, int l) {
22 | return "resolved two string and two integers";
23 | }
24 |
25 | public static String resolve(String i, String j, int... integers) {
26 | return "resolved two args and varargs";
27 | }
28 |
29 | public static String resolve(int... integers) {
30 | return "resolved varargs";
31 | }
32 |
33 | public static String resolve(int i, long j, String k) {
34 | return "resolved one int, one long and a string";
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/tests/java-src/org/jnius/ObjectArgument.java:
--------------------------------------------------------------------------------
1 | package org.jnius;
2 |
3 |
4 | public class ObjectArgument {
5 | public static int checkObject(Object obj) {
6 | if (obj == null) {
7 | return -1;
8 | } else {
9 | return 0;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/tests/java-src/org/jnius/Parent.java:
--------------------------------------------------------------------------------
1 | package org.jnius;
2 |
3 | public class Parent {
4 |
5 | public static int STATIC_PARENT_FIELD = 1;
6 |
7 | public int doCall(Object o) {
8 | return 0;
9 | }
10 |
11 | public int getParentStaticField() {
12 | return STATIC_PARENT_FIELD;
13 | }
14 |
15 | public static int StaticGetParentStaticField() {
16 | return STATIC_PARENT_FIELD;
17 | }
18 |
19 | public int getParentField() {
20 | return PARENT_FIELD;
21 | }
22 |
23 | static public Parent newInstance(){
24 | return new Parent();
25 | }
26 |
27 | public int PARENT_FIELD = 0;
28 | }
29 |
--------------------------------------------------------------------------------
/tests/java-src/org/jnius/SimpleEnum.java:
--------------------------------------------------------------------------------
1 | package org.jnius;
2 |
3 |
4 | public enum SimpleEnum {
5 | GOOD, BAD, UGLY,
6 | }
7 |
--------------------------------------------------------------------------------
/tests/java-src/org/jnius/VariableArgConstructors.java:
--------------------------------------------------------------------------------
1 | package org.jnius;
2 |
3 | public class VariableArgConstructors {
4 | public int constructorUsed;
5 |
6 | public VariableArgConstructors(int arg1, String arg2, int arg3, Object arg4, int... arg5) {
7 | constructorUsed = 1;
8 | }
9 |
10 | public VariableArgConstructors(int arg1, String arg2, Object arg3, int... arg4) {
11 | constructorUsed = 2;
12 | }
13 |
14 | }
--------------------------------------------------------------------------------
/tests/java-src/org/jnius/VariablePassing.java:
--------------------------------------------------------------------------------
1 | package org.jnius;
2 |
3 | public class VariablePassing {
4 |
5 | public VariablePassing() {
6 |
7 | }
8 |
9 | public VariablePassing(int[] numbers) {
10 | squareNumbers(numbers);
11 | }
12 |
13 | public VariablePassing(int[] numbers1, int[] numbers2, int[] numbers3, int[] numbers4) {
14 | squareNumbers(numbers1);
15 | squareNumbers(numbers2);
16 | squareNumbers(numbers3);
17 | squareNumbers(numbers4);
18 | }
19 |
20 | private static void squareNumbers(int[] numbers) {
21 | for (int i = 0; i < numbers.length; i++) {
22 | numbers[i] = i * i;
23 | }
24 | }
25 |
26 | public static void singleParamStatic(int[] numbers) {
27 | squareNumbers(numbers);
28 | }
29 |
30 | public static void multipleParamsStatic(int[] numbers1, int[] numbers2, int[] numbers3, int[] numbers4) {
31 | squareNumbers(numbers1);
32 | squareNumbers(numbers2);
33 | squareNumbers(numbers3);
34 | squareNumbers(numbers4);
35 | }
36 |
37 | public void singleParam(int[] numbers) {
38 | squareNumbers(numbers);
39 | }
40 |
41 | public void multipleParams(int[] numbers1, int[] numbers2, int[] numbers3, int[] numbers4) {
42 | squareNumbers(numbers1);
43 | squareNumbers(numbers2);
44 | squareNumbers(numbers3);
45 | squareNumbers(numbers4);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/tests/java-src/org/jnius/VisibilityTest.java:
--------------------------------------------------------------------------------
1 | package org.jnius;
2 |
3 | import java.lang.String;
4 |
5 | public class VisibilityTest {
6 | public String fieldPublic = "Public";
7 | String fieldPackageProtected = "PackageProtected";
8 | protected String fieldProtected = "Protected";
9 | private String fieldPrivate = "Private";
10 |
11 | static public String fieldStaticPublic = "StaticPublic";
12 | static String fieldStaticPackageProtected = "StaticPackageProtected";
13 | static protected String fieldStaticProtected = "StaticProtected";
14 | static private String fieldStaticPrivate = "StaticPrivate";
15 |
16 | public String methodPublic() {
17 | return fieldPublic;
18 | }
19 |
20 | String methodPackageProtected() {
21 | return fieldPackageProtected;
22 | }
23 |
24 | protected String methodProtected() {
25 | return fieldProtected;
26 | }
27 |
28 | private String methodPrivate() {
29 | return fieldPrivate;
30 | }
31 |
32 | public boolean methodMultiArgs(boolean a) {
33 | return a;
34 | }
35 |
36 | // dummy method to avoid warning methodPrivate() isn't used
37 | public String methodDummy() {
38 | return this.methodPrivate();
39 | }
40 |
41 | static public String methodStaticPublic() {
42 | return fieldStaticPublic;
43 | }
44 |
45 | static String methodStaticPackageProtected() {
46 | return fieldStaticPackageProtected;
47 | }
48 |
49 | static protected String methodStaticProtected() {
50 | return fieldStaticProtected;
51 | }
52 |
53 | static private String methodStaticPrivate() {
54 | return fieldStaticPrivate;
55 | }
56 |
57 | static public boolean methodStaticMultiArgs(boolean a) {
58 | return a;
59 | }
60 |
61 | // dummy method to avoid warning methodStaticPrivate() isn't used
62 | static public String methodStaticDummy() {
63 | return VisibilityTest.methodStaticPrivate();
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/tests/java-src/org/jnius2/ChildVisibilityTest.java:
--------------------------------------------------------------------------------
1 | package org.jnius2;
2 |
3 | import java.lang.String;
4 |
5 | import org.jnius.VisibilityTest;
6 |
7 | public class ChildVisibilityTest extends VisibilityTest {
8 | public String fieldChildPublic = "ChildPublic";
9 | String fieldChildPackageProtected = "ChildPackageProtected";
10 | protected String fieldChildProtected = "ChildProtected";
11 | private String fieldChildPrivate = "ChildPrivate";
12 |
13 | static public String fieldChildStaticPublic = "ChildStaticPublic";
14 | static String fieldChildStaticPackageProtected = "ChildStaticPackageProtected";
15 | static protected String fieldChildStaticProtected = "ChildStaticProtected";
16 | static private String fieldChildStaticPrivate = "ChildStaticPrivate";
17 |
18 | public String methodChildPublic() {
19 | return fieldChildPublic;
20 | }
21 |
22 | String methodChildPackageProtected() {
23 | return fieldChildPackageProtected;
24 | }
25 |
26 | protected String methodChildProtected() {
27 | return fieldChildProtected;
28 | }
29 |
30 | private String methodChildPrivate() {
31 | return fieldChildPrivate;
32 | }
33 |
34 | protected boolean methodMultiArgs(boolean a, boolean b) {
35 | return a & !b;
36 | }
37 |
38 | private boolean methodMultiArgs(boolean a, boolean b, boolean c) {
39 | return a & !b & c;
40 | }
41 |
42 | // dummy method to avoid warning about unused methods
43 | public String methodChildDummy() {
44 | this.methodMultiArgs(true, true, false);
45 | return this.methodChildPrivate();
46 | }
47 |
48 | static public String methodChildStaticPublic() {
49 | return fieldChildStaticPublic;
50 | }
51 |
52 | static String methodChildStaticPackageProtected() {
53 | return fieldChildStaticPackageProtected;
54 | }
55 |
56 | static protected String methodChildStaticProtected() {
57 | return fieldChildStaticProtected;
58 | }
59 |
60 | static private String methodChildStaticPrivate() {
61 | return fieldChildStaticPrivate;
62 | }
63 |
64 | static protected boolean methodStaticMultiArgs(boolean a, boolean b) {
65 | return a & !b;
66 | }
67 |
68 | static private boolean methodStaticMultiArgs(boolean a, boolean b, boolean c) {
69 | return a & !b & c;
70 | }
71 |
72 | // dummy method to avoid warning about unused methods
73 | static public String methodChildStaticDummy() {
74 | ChildVisibilityTest.methodStaticMultiArgs(true, true, true);
75 | return ChildVisibilityTest.methodChildStaticPrivate();
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/tests/test_arraylist.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import
2 | import unittest
3 | from jnius import autoclass
4 |
5 |
6 | class ArrayListTest(unittest.TestCase):
7 |
8 | def test_other_dunders(self):
9 | alist = autoclass('java.util.ArrayList')()
10 | args = [1,2]
11 | for arg in args:
12 | alist.add(arg)
13 | self.assertEqual(len(args), len(alist))
14 | for idx, arg in enumerate(args):
15 | self.assertTrue(arg in alist)
16 | del(alist[1])
17 | del(alist[0])
18 | self.assertEqual(0, len(alist))
19 |
20 | def test_output(self):
21 | alist = autoclass('java.util.ArrayList')()
22 | args = [0, 1, 5, -1, -5, 0.0, 1.0, 5.0, -1.0, -5.0, True, False]
23 |
24 | for arg in args:
25 | alist.add(arg)
26 | for idx, arg in enumerate(args):
27 | if isinstance(arg, bool):
28 | self.assertEqual(str(alist[idx]), str(int(arg)))
29 | else:
30 | self.assertEqual(str(alist[idx]), str(arg))
31 | self.assertEqual(len(args), len(alist))
32 |
33 |
34 | if __name__ == '__main__':
35 | unittest.main()
36 |
--------------------------------------------------------------------------------
/tests/test_assignable.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | from __future__ import division
3 | from __future__ import absolute_import
4 | import unittest
5 | from jnius import autoclass, JavaException
6 |
7 |
8 | class AssignableFrom(unittest.TestCase):
9 |
10 | def test_assignable(self):
11 | ArrayList = autoclass('java.util.ArrayList')
12 | Object = autoclass('java.lang.Object')
13 |
14 | a = ArrayList()
15 | # addAll accept Collection, Object must failed
16 | with self.assertRaisesRegex(TypeError, "Invalid instance of 'java/lang/Object' passed for a 'java/util/Collection'"):
17 | a.addAll(Object())
18 |
19 | # while adding another ArrayList must be ok.
20 | a.addAll(ArrayList())
21 |
--------------------------------------------------------------------------------
/tests/test_bad_declaration.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | from __future__ import division
3 | from __future__ import absolute_import
4 | import unittest
5 | from jnius import JavaException, JavaClass
6 | from jnius.reflect import autoclass
7 |
8 | class BadDeclarationTest(unittest.TestCase):
9 |
10 | def test_class_not_found(self):
11 | #self.assertRaises(JavaException, autoclass, 'org.unknow.class')
12 | #self.assertRaises(JavaException, autoclass, 'java/lang/String')
13 | pass
14 |
15 | def test_invalid_attribute(self):
16 | Stack = autoclass('java.util.Stack')
17 | self.assertRaises(AttributeError, getattr, Stack, 'helloworld')
18 |
19 | def test_invalid_static_call(self):
20 | Stack = autoclass('java.util.Stack')
21 | self.assertRaises(JavaException, Stack.push, 'hello')
22 |
23 | def test_with_too_much_arguments(self):
24 | Stack = autoclass('java.util.Stack')
25 | stack = Stack()
26 | self.assertRaises(JavaException, stack.push, 'hello', 'world', 123)
27 |
28 | def test_java_exception_handling(self):
29 | Stack = autoclass('java.util.Stack')
30 | stack = Stack()
31 | try:
32 | stack.pop()
33 | self.fail("Expected exception to be thrown")
34 | except JavaException as je:
35 | # print "Got JavaException: " + str(je)
36 | # print "Got Exception Class: " + je.classname
37 | # print "Got stacktrace: \n" + '\n'.join(je.stacktrace)
38 | self.assertEqual("java.util.EmptyStackException", je.classname)
39 |
40 | def test_java_exception_chaining(self):
41 | BasicsTest = autoclass('org.jnius.BasicsTest')
42 | basics = BasicsTest()
43 | try:
44 | basics.methodExceptionChained()
45 | self.fail("Expected exception to be thrown")
46 | except JavaException as je:
47 | # print "Got JavaException: " + str(je)
48 | # print "Got Exception Class: " + je.classname
49 | # print "Got Exception Message: " + je.innermessage
50 | # print "Got stacktrace: \n" + '\n'.join(je.stacktrace)
51 | self.assertEqual("java.lang.IllegalArgumentException", je.classname)
52 | self.assertEqual("helloworld2", je.innermessage)
53 | self.assertIn("Caused by:", je.stacktrace)
54 | self.assertEqual(11, len(je.stacktrace))
55 |
--------------------------------------------------------------------------------
/tests/test_basics.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | from __future__ import division
3 | from __future__ import absolute_import
4 | import unittest
5 | from jnius.reflect import autoclass
6 |
7 |
8 | class BasicsTest(unittest.TestCase):
9 |
10 | def test_static_methods(self):
11 | Test = autoclass('org.jnius.BasicsTest')
12 | self.assertEqual(Test.methodStaticZ(), True)
13 | self.assertEqual(Test.methodStaticB(), 127)
14 | self.assertEqual(Test.methodStaticC(), 'k')
15 | self.assertEqual(Test.methodStaticS(), 32767)
16 | self.assertEqual(Test.methodStaticI(), 2147483467)
17 | self.assertEqual(Test.methodStaticJ(), 9223372036854775807)
18 | self.assertAlmostEqual(Test.methodStaticF(), 1.23456789)
19 | self.assertEqual(Test.methodStaticD(), 1.23456789)
20 | self.assertEqual(Test.methodStaticString(), 'hello \U0001F30E!')
21 |
22 | def test_static_fields(self):
23 | Test = autoclass('org.jnius.BasicsTest')
24 | self.assertEqual(Test.fieldStaticZ, True)
25 | self.assertEqual(Test.fieldStaticB, 127)
26 | self.assertEqual(Test.fieldStaticC, 'k')
27 | self.assertEqual(Test.fieldStaticS, 32767)
28 | self.assertEqual(Test.fieldStaticI, 2147483467)
29 | self.assertEqual(Test.fieldStaticJ, 9223372036854775807)
30 | self.assertAlmostEqual(Test.fieldStaticF, 1.23456789)
31 | self.assertEqual(Test.fieldStaticD, 1.23456789)
32 | self.assertEqual(Test.fieldStaticString, 'hello \U0001F30E!')
33 |
34 | def test_instance_methods(self):
35 | test = autoclass('org.jnius.BasicsTest')()
36 | self.assertEqual(test.methodZ(), True)
37 | self.assertEqual(test.methodB(), 127)
38 | self.assertEqual(test.methodC(), 'k')
39 | self.assertEqual(test.methodS(), 32767)
40 | self.assertEqual(test.methodI(), 2147483467)
41 | self.assertEqual(test.methodJ(), 9223372036854775807)
42 | self.assertAlmostEqual(test.methodF(), 1.23456789)
43 | self.assertEqual(test.methodD(), 1.23456789)
44 | self.assertEqual(test.methodString(), 'hello \U0001F30E!')
45 |
46 | def test_instance_fields(self):
47 | test = autoclass('org.jnius.BasicsTest')()
48 | self.assertEqual(test.fieldZ, True)
49 | self.assertEqual(test.fieldB, 127)
50 | self.assertEqual(test.fieldC, 'k')
51 | self.assertEqual(test.fieldS, 32767)
52 | self.assertEqual(test.fieldI, 2147483467)
53 | self.assertEqual(test.fieldJ, 9223372036854775807)
54 | self.assertAlmostEqual(test.fieldF, 1.23456789)
55 | self.assertEqual(test.fieldD, 1.23456789)
56 | self.assertEqual(test.fieldString, 'hello \U0001F30E!')
57 | test2 = autoclass('org.jnius.BasicsTest')(10)
58 | self.assertEqual(test2.fieldB, 10)
59 | self.assertEqual(test.fieldB, 127)
60 | self.assertEqual(test2.fieldB, 10)
61 |
62 | def test_instance_getter_naming(self):
63 | test = autoclass('org.jnius.BasicsTest')()
64 | self.assertEqual(test.disabled, True)
65 | self.assertEqual(test.enabled, False)
66 |
67 | def test_instance_set_fields(self):
68 | test = autoclass('org.jnius.BasicsTest')()
69 | test.fieldSetZ = True
70 | test.fieldSetB = 127
71 | test.fieldSetC = ord('k')
72 | test.fieldSetS = 32767
73 | test.fieldSetI = 2147483467
74 | test.fieldSetJ = 9223372036854775807
75 | test.fieldSetF = 1.23456789
76 | test.fieldSetD = 1.23456789
77 |
78 | self.assertTrue(test.testFieldSetZ())
79 | self.assertTrue(test.testFieldSetB())
80 | self.assertTrue(test.testFieldSetC())
81 | self.assertTrue(test.testFieldSetS())
82 | self.assertTrue(test.testFieldSetI())
83 | self.assertTrue(test.testFieldSetJ())
84 | self.assertTrue(test.testFieldSetF())
85 | self.assertTrue(test.testFieldSetD())
86 |
87 | def test_instances_methods_array(self):
88 | test = autoclass('org.jnius.BasicsTest')()
89 | self.assertEqual(test.methodArrayZ(), [True] * 3)
90 | self.assertEqual(test.methodArrayB()[0], 127)
91 | self.assertEqual(test.methodArrayB(), [127] * 3)
92 | self.assertEqual(test.methodArrayC(), ['k'] * 3)
93 | self.assertEqual(test.methodArrayS(), [32767] * 3)
94 | self.assertEqual(test.methodArrayI(), [2147483467] * 3)
95 | self.assertEqual(test.methodArrayJ(), [9223372036854775807] * 3)
96 |
97 | ret = test.methodArrayF()
98 | ref = [1.23456789] * 3
99 | self.assertAlmostEqual(ret[0], ref[0])
100 | self.assertAlmostEqual(ret[1], ref[1])
101 | self.assertAlmostEqual(ret[2], ref[2])
102 |
103 | self.assertEqual(test.methodArrayD(), [1.23456789] * 3)
104 | self.assertEqual(test.methodArrayString(), ['hello \U0001F30E!'] * 3)
105 |
106 | def test_instances_methods_params(self):
107 | test = autoclass('org.jnius.BasicsTest')()
108 | self.assertEqual(test.methodParamsZBCSIJFD(
109 | True, 127, 'k', 32767, 2147483467, 9223372036854775807, 1.23456789, 1.23456789), True)
110 | self.assertEqual(test.methodParamsString('hello \U0001F30E!'), True)
111 | self.assertEqual(test.methodParamsArrayI([1, 2, 3]), True)
112 | self.assertEqual(test.methodParamsArrayString([
113 | 'hello', '\U0001F30E']), True)
114 |
115 | def test_instances_methods_params_object_list_str(self):
116 | test = autoclass('org.jnius.BasicsTest')()
117 | self.assertEqual(test.methodParamsObject([
118 | 'hello', 'world']), True)
119 |
120 | def test_instances_methods_params_object_list_int(self):
121 | test = autoclass('org.jnius.BasicsTest')()
122 | self.assertEqual(test.methodParamsObject([1, 2]), True)
123 |
124 | def test_instances_methods_params_object_list_float(self):
125 | test = autoclass('org.jnius.BasicsTest')()
126 | self.assertEqual(test.methodParamsObject([3.14, 1.61]), True)
127 |
128 | def test_instances_methods_params_array_byte(self):
129 | test = autoclass('org.jnius.BasicsTest')()
130 | self.assertEqual(test.methodParamsArrayByte([127, 127, 127]), True)
131 | ret = test.methodArrayB()
132 | self.assertEqual(test.methodParamsArrayByte(ret), True)
133 |
134 | def test_return_array_as_object_array_of_strings(self):
135 | test = autoclass('org.jnius.BasicsTest')()
136 | self.assertEqual(test.methodReturnStrings(), ['Hello',
137 | '\U0001F30E'])
138 |
139 | def test_return_array_as_object_of_integers(self):
140 | test = autoclass('org.jnius.BasicsTest')()
141 | self.assertEqual(test.methodReturnIntegers(), [1, 2])
142 |
--------------------------------------------------------------------------------
/tests/test_bytearray.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | from __future__ import division
3 | from __future__ import absolute_import
4 | import unittest
5 | from jnius import autoclass
6 |
7 | class StringArgumentForByteArrayTest(unittest.TestCase):
8 |
9 | def test_string_arg_for_byte_array(self):
10 | # the ByteBuffer.wrap() accept only byte[].
11 | ByteBuffer = autoclass('java.nio.ByteBuffer')
12 | self.assertIsNotNone(ByteBuffer.wrap(b'hello world'))
13 |
14 | def test_string_arg_with_signed_char(self):
15 | ByteBuffer = autoclass('java.nio.ByteBuffer')
16 | self.assertIsNotNone(ByteBuffer.wrap(b'\x00\xffHello World\x7f'))
17 |
18 | def test_fill_byte_array(self):
19 | arr = [0, 0, 0]
20 | Test = autoclass('org.jnius.BasicsTest')()
21 | Test.fillByteArray(arr)
22 | # we don't received signed byte, but unsigned in python.
23 | self.assertEqual(
24 | arr,
25 | [127, 1, 129])
26 |
27 | def test_create_bytearray(self):
28 | StringBufferInputStream = autoclass('java.io.StringBufferInputStream')
29 | nis = StringBufferInputStream("Hello world")
30 | barr = bytearray("\x00" * 5, encoding="utf8")
31 | self.assertEqual(nis.read(barr, 0, 5), 5)
32 | self.assertEqual(barr, b"Hello")
33 |
34 | def test_bytearray_ascii(self):
35 | ByteArrayInputStream = autoclass('java.io.ByteArrayInputStream')
36 | s = b"".join(bytes(x) for x in range(256))
37 | nis = ByteArrayInputStream(s)
38 | barr = bytearray("\x00" * 256, encoding="ascii")
39 | self.assertEqual(nis.read(barr, 0, 256), 256)
40 | self.assertEqual(barr[:256], s[:256])
41 |
42 | def test_empty_bytearray(self):
43 | Test = autoclass('org.jnius.BasicsTest')()
44 | arr = Test.methodReturnEmptyByteArray()
45 | self.assertEqual(len(arr), 0)
46 | with self.assertRaises(IndexError):
47 | arr[0]
48 | self.assertEqual(arr, [])
49 | self.assertEqual(arr[:1], [])
50 | self.assertEqual(arr.tostring(), b'')
51 |
--------------------------------------------------------------------------------
/tests/test_cast.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | from __future__ import division
3 | from __future__ import absolute_import
4 | import unittest
5 | from jnius.reflect import autoclass
6 | from jnius import cast
7 |
8 |
9 | class MultipleSignatureTest(unittest.TestCase):
10 | def test_multiple_constructors(self):
11 | String = autoclass('java.lang.String')
12 | s = String('hello world')
13 | self.assertEqual(s.__javaclass__, 'java/lang/String')
14 | o = cast('java.lang.Object', s)
15 | self.assertEqual(o.__javaclass__, 'java/lang/Object')
16 |
17 | def test_mmap_toString(self):
18 | mapClass = autoclass('java.util.HashMap')
19 | hmap = mapClass()
20 | hmap.put("a", "1")
21 | hmap.toString()
22 | mmap = cast('java.util.Map', hmap)
23 | mmap.toString()
24 | mmap.getClass()
25 |
--------------------------------------------------------------------------------
/tests/test_chars_and_strings.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # from __future__ import print_function
3 | from __future__ import division
4 | from __future__ import absolute_import
5 | import unittest
6 | from jnius.reflect import autoclass, JavaException
7 |
8 |
9 | class CharsAndStringsTest(unittest.TestCase):
10 |
11 | def test_char_fields(self):
12 | Test = autoclass('org.jnius.CharsAndStrings',
13 | include_protected=False, include_private=False)
14 | test = Test()
15 |
16 | self.assertEqual(test.testChar1, 'a')
17 | self.assertEqual(test.testChar2, 'ä')
18 | self.assertEqual(test.testChar3, '☺')
19 |
20 | self.assertEqual(Test.testStaticChar1, 'a')
21 | self.assertEqual(Test.testStaticChar2, 'ä')
22 | self.assertEqual(Test.testStaticChar3, '☺')
23 |
24 | def test_string_fields(self):
25 | Test = autoclass('org.jnius.CharsAndStrings',
26 | include_protected=False, include_private=False)
27 | test = Test()
28 |
29 | self.assertEqual(test.testString1, "hello world")
30 | self.assertEqual(test.testString2, "umlauts: äöü")
31 | self.assertEqual(test.testString3, "happy face: ☺")
32 |
33 | self.assertEqual(Test.testStaticString1, "hello world")
34 | self.assertEqual(Test.testStaticString2, "umlauts: äöü")
35 | self.assertEqual(Test.testStaticString3, "happy face: ☺")
36 |
37 | def test_char_methods(self):
38 | Test = autoclass('org.jnius.CharsAndStrings',
39 | include_protected=False, include_private=False)
40 | test = Test()
41 |
42 | self.assertEqual(test.testChar(1, 'a'), 'a')
43 | self.assertEqual(test.testChar(2, 'ä'), 'ä')
44 | self.assertEqual(test.testChar(3, '☺'), '☺')
45 |
46 | self.assertEqual(Test.testStaticChar(1, 'a'), 'a')
47 | self.assertEqual(Test.testStaticChar(2, 'ä'), 'ä')
48 | self.assertEqual(Test.testStaticChar(3, '☺'), '☺')
49 |
50 | def test_string_methods(self):
51 | Test = autoclass('org.jnius.CharsAndStrings',
52 | include_protected=False, include_private=False)
53 | test = Test()
54 |
55 | self.assertEqual(test.testString(1, "hello world"), "hello world")
56 | self.assertEqual(test.testString(2, "umlauts: äöü"), "umlauts: äöü")
57 | self.assertEqual(test.testString(3, "happy face: ☺"), "happy face: ☺")
58 |
59 | self.assertEqual(Test.testStaticString(1, "hello world"), "hello world")
60 | self.assertEqual(Test.testStaticString(2, "umlauts: äöü"), "umlauts: äöü")
61 | self.assertEqual(Test.testStaticString(3, "happy face: ☺"), "happy face: ☺")
62 |
63 | def test_char_array(self):
64 | Test = autoclass('org.jnius.CharsAndStrings',
65 | include_protected=False, include_private=False)
66 | test = Test()
67 |
68 | charArray1 = ['a', 'b', 'c']
69 | charArray2 = ['a', 'ä', '☺']
70 |
71 | for c1, c2 in zip(charArray1, test.testCharArray1):
72 | self.assertEqual(c1, c2)
73 | for c1, c2 in zip(charArray1, test.testCharArray(1)):
74 | self.assertEqual(c1, c2)
75 | for c1, c2 in zip(charArray2, test.testCharArray2):
76 | self.assertEqual(c1, c2)
77 | for c1, c2 in zip(charArray2, test.testCharArray(2)):
78 | self.assertEqual(c1, c2)
79 |
80 | def test_static_char_array(self):
81 | Test = autoclass('org.jnius.CharsAndStrings',
82 | include_protected=False, include_private=False)
83 |
84 | charArray1 = ['a', 'b', 'c']
85 | charArray2 = ['a', 'ä', '☺']
86 |
87 | for c1, c2 in zip(charArray1, Test.testStaticCharArray1):
88 | self.assertEqual(c1, c2)
89 | for c1, c2 in zip(charArray1, Test.testStaticCharArray(1)):
90 | self.assertEqual(c1, c2)
91 | for c1, c2 in zip(charArray2, Test.testStaticCharArray2):
92 | self.assertEqual(c1, c2)
93 | for c1, c2 in zip(charArray2, Test.testStaticCharArray(2)):
94 | self.assertEqual(c1, c2)
95 |
96 |
97 | def test_java_string(self):
98 | JString = autoclass('java.lang.String')
99 |
100 | testString1 = JString('hello world')
101 | self.assertTrue(testString1.equals('hello world'))
102 | testString2 = JString('umlauts: äöü')
103 | self.assertTrue(testString2.equals('umlauts: äöü'))
104 | testString3 = JString('happy face: ☺')
105 | self.assertTrue(testString3.equals('happy face: ☺'))
106 |
107 | # two methods below are concerned with type-checking of arguments
108 |
109 | def test_pass_intfloat_as_string(self):
110 | CharsAndStrings = autoclass("org.jnius.CharsAndStrings")
111 | self.assertIsNone(CharsAndStrings.testStringDefNull)
112 | with self.assertRaisesRegex(TypeError, "Invalid instance of 'java/lang/Integer' passed for a 'java/lang/String'"):
113 | # we cannot provide an int to a String
114 | CharsAndStrings.setString("a", 2)
115 | with self.assertRaisesRegex(TypeError, "Invalid instance of 'java/lang/Float' passed for a 'java/lang/String'"):
116 | # we cannot provide an float to a String
117 | CharsAndStrings.setString("a", 2.2)
118 | alist = autoclass("java.util.ArrayList")()
119 | with self.assertRaisesRegex(TypeError, "Invalid instance of 'java/util/ArrayList' passed for a 'java/lang/String'"):
120 | # we cannot provide a list to a String
121 | CharsAndStrings.setString("a", alist)
122 | system = autoclass("java.lang.System")
123 | with self.assertRaises(JavaException):
124 | system.setErr("a string")
125 |
126 | def test_pass_string_as_int(self):
127 | CharsAndStrings = autoclass("org.jnius.CharsAndStrings")
128 | self.assertEqual(0, CharsAndStrings.testInt)
129 | with self.assertRaisesRegex(TypeError, "an integer is required"):
130 | # we cannot provide a String to an int
131 | CharsAndStrings.setInt("a", "2")
132 |
--------------------------------------------------------------------------------
/tests/test_class_argument.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | from __future__ import division
3 | from __future__ import absolute_import
4 | import unittest
5 | from jnius.reflect import autoclass
6 |
7 | class BasicsTest(unittest.TestCase):
8 |
9 | def test_static_methods(self):
10 | ClassArgument = autoclass('org.jnius.ClassArgument')
11 | self.assertEqual(ClassArgument.getName(ClassArgument), 'class org.jnius.ClassArgument')
12 |
--------------------------------------------------------------------------------
/tests/test_closeable.py:
--------------------------------------------------------------------------------
1 | '''
2 | Test creating for java.io.Closeable dunder
3 | '''
4 |
5 | from __future__ import absolute_import
6 | import unittest
7 | from jnius import autoclass, JavaException, protocol_map
8 |
9 |
10 | class TestCloseable(unittest.TestCase):
11 | '''
12 | TestCase for using java.io.Closeable dunder
13 | '''
14 |
15 | def test_stringreader_closeable(self):
16 | '''
17 | this checkes that java.lang.AutoCloseable instances gain
18 | the correct dunder methods
19 | '''
20 | swCheck = autoclass("java.io.StringWriter")()
21 | self.assertTrue("__enter__" in dir(swCheck))
22 | self.assertTrue("__exit__" in dir(swCheck))
23 |
24 | with autoclass("java.io.StringWriter")() as sw:
25 | sw.write("Hello")
26 |
27 | def test_our_closeable(self):
28 | '''
29 | this checkes that closeable dunder methods are actually called
30 | org.jnius.CloseableClass has java.io.Closeable, to differ from
31 | java.lang.AutoCloseable (which is what is in interface_map)
32 | '''
33 | ourcloseableClz = autoclass("org.jnius.CloseableClass")
34 | self.assertTrue("__enter__" in dir(ourcloseableClz()))
35 | self.assertTrue("__exit__" in dir(ourcloseableClz()))
36 |
37 | self.assertTrue(ourcloseableClz.open)
38 | with ourcloseableClz() as ourcloseable2:
39 | self.assertTrue(ourcloseableClz.open)
40 | self.assertFalse(ourcloseableClz.open)
41 |
42 | def test_protocol_map(self):
43 | self.assertTrue("java.util.List" in protocol_map)
44 |
--------------------------------------------------------------------------------
/tests/test_collections.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import
2 | import unittest
3 | from jnius import autoclass, protocol_map
4 |
5 |
6 | class TestCollections(unittest.TestCase):
7 |
8 | def test_hashset(self):
9 | hset = autoclass('java.util.HashSet')()
10 | data = {1,2}
11 | # add is in both Python and Java
12 | for k in data:
13 | hset.add(k)
14 | # __len__
15 | print(dir(hset))
16 | self.assertEqual(len(data), len(hset))
17 | # __contains__
18 | for k in data:
19 | self.assertTrue(k in hset)
20 | self.assertFalse(0 in hset)
21 | # __iter__
22 | for k in hset:
23 | self.assertTrue(k in data)
24 | # __delitem__
25 | for k in data:
26 | del(hset[k])
27 | self.assertFalse(k in hset)
28 |
29 | def test_hashmap(self):
30 | hmap = autoclass('java.util.HashMap')()
31 | data = {1 : 'hello', 2 : 'world'}
32 | # __setitem__
33 | for k,v in data.items():
34 | hmap[k] = v
35 | # __len__
36 | self.assertEqual(len(data), len(hmap))
37 | # __contains__
38 | for k,v in data.items():
39 | self.assertTrue(k in hmap)
40 | self.assertEqual(data[k], hmap[k])
41 | # __iter__
42 | for k in hmap:
43 | self.assertTrue(k in data)
44 | # __map_entry__
45 | for k,v in hmap.entrySet():
46 | self.assertEqual(data[k], v)
47 | # __contains__
48 | self.assertFalse(0 in hmap)
49 | # __delitem__
50 | for k in data:
51 | del(hmap[k])
52 | self.assertFalse(k in hmap)
53 |
54 | if __name__ == '__main__':
55 | unittest.main()
56 |
--------------------------------------------------------------------------------
/tests/test_comparable.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import
2 | import unittest
3 | from jnius import autoclass, protocol_map
4 |
5 | class ComparableTest(unittest.TestCase):
6 | def __init__(self, *args, **kwargs):
7 | super(ComparableTest, self).__init__(*args, **kwargs)
8 |
9 | def test_compare_integer(self):
10 | five = autoclass('java.lang.Integer')(5)
11 | six = autoclass('java.lang.Integer')(6)
12 | six_two = autoclass('java.lang.Integer')(6)
13 | self.assertTrue(five < six)
14 | self.assertTrue(six > five)
15 | self.assertTrue(six == six_two)
16 | self.assertTrue(five <= six)
17 | self.assertTrue(six >= five)
18 | self.assertTrue(six >= six_two)
19 | self.assertTrue(six <= six_two)
20 |
21 | if __name__ == '__main__':
22 | unittest.main()
--------------------------------------------------------------------------------
/tests/test_constructor.py:
--------------------------------------------------------------------------------
1 | '''
2 | Test creating an instance of a Java class and fetching its values.
3 | '''
4 |
5 | from __future__ import absolute_import
6 | import unittest
7 | from jnius import autoclass, JavaException
8 |
9 |
10 | class TestConstructor(unittest.TestCase):
11 | '''
12 | TestCase for using constructors with PyJNIus.
13 | '''
14 |
15 | def test_constructor_none(self):
16 | '''
17 | Empty constructor, baked value in the .java file.
18 | '''
19 |
20 | ConstructorTest = autoclass('org.jnius.ConstructorTest')
21 | inst = ConstructorTest()
22 | self.assertEqual(inst.ret, 753)
23 | self.assertTrue(ConstructorTest._class.isInstance(inst))
24 | self.assertTrue(inst.getClass().isInstance(inst))
25 |
26 | def test_constructor_int(self):
27 | '''
28 | Constructor expecting int and setting it as public 'ret' property.
29 | '''
30 |
31 | ConstructorTest = autoclass('org.jnius.ConstructorTest')
32 | inst = ConstructorTest(123)
33 | self.assertEqual(inst.ret, 123)
34 | self.assertTrue(ConstructorTest._class.isInstance(inst))
35 | self.assertTrue(inst.getClass().isInstance(inst))
36 |
37 | def test_constructor_string(self):
38 | '''
39 | Constructor expecting char, casting it to int and setting it
40 | as public 'ret' property.
41 | '''
42 |
43 | ConstructorTest = autoclass('org.jnius.ConstructorTest')
44 | inst = ConstructorTest('a')
45 | self.assertEqual(inst.ret, ord('a'))
46 | self.assertTrue(ConstructorTest._class.isInstance(inst))
47 | self.assertTrue(inst.getClass().isInstance(inst))
48 |
49 | def test_constructor_multiobj(self):
50 | '''
51 | Constructor expecting String.
52 | '''
53 |
54 | outputStream = autoclass('java.lang.System').out
55 | ConstructorTest = autoclass('org.jnius.ConstructorTest')
56 | inst = ConstructorTest(outputStream, signature="(Ljava/io/OutputStream;)V")
57 | self.assertEqual(inst.ret, 42)
58 | self.assertTrue(ConstructorTest._class.isInstance(inst))
59 | self.assertTrue(inst.getClass().isInstance(inst))
60 |
61 | def test_constructor_int_string(self):
62 | '''
63 | Constructor expecting int and char, casting char to int and summing it
64 | as public 'ret' property.
65 | '''
66 |
67 | ConstructorTest = autoclass('org.jnius.ConstructorTest')
68 | inst = ConstructorTest(3, 'a')
69 | self.assertEqual(inst.ret, 3 + ord('a'))
70 | self.assertTrue(ConstructorTest._class.isInstance(inst))
71 | self.assertTrue(inst.getClass().isInstance(inst))
72 |
73 | def test_constructor_exception(self):
74 | '''
75 | No such constructor found (no such signature),
76 | should raise JavaException.
77 | '''
78 |
79 | ConstructorTest = autoclass('org.jnius.ConstructorTest')
80 | with self.assertRaises(JavaException):
81 | ConstructorTest('1.', 2.0, False)
82 |
83 |
84 | if __name__ == '__main__':
85 | unittest.main()
86 |
--------------------------------------------------------------------------------
/tests/test_dir.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | from __future__ import division
3 | from __future__ import absolute_import
4 | import unittest
5 | from jnius.reflect import autoclass
6 |
7 | class DirTest(unittest.TestCase):
8 |
9 | def test_varargs_signatures(self):
10 | # >>> from jnius import autoclass
11 | # >>> cls = autoclass('java.lang.System')
12 | # >>> cls.out.printf.signatures()
13 | # [(['java/lang/String', 'java/lang/Object...'], 'java/io/PrintStream'),
14 | # (['java/util/Locale', 'java/lang/String', 'java/lang/Object...'], 'java/io/PrintStream')]
15 |
16 | cls = autoclass("java.lang.System")
17 | result = cls.out.printf.signatures()
18 |
19 | assert isinstance(result, list)
20 | assert all(isinstance(f, tuple) for f in result)
21 |
22 | assert (['java/lang/String', 'java/lang/Object...'], 'java/io/PrintStream') in result
23 | assert (['java/util/Locale', 'java/lang/String', 'java/lang/Object...'], 'java/io/PrintStream') in result
24 |
25 | def test_array_signatures(self):
26 | # >>> from jnius import autoclass
27 | # >>> cls = autoclass('java.util.List')
28 | # >>> cls.toArray.signatures()
29 | # [([], 'java/lang/Object[]'),
30 | # (['java/lang/Object[]'], 'java/lang/Object[]')]
31 |
32 | cls = autoclass("java.util.List")
33 | result = cls.toArray.signatures()
34 |
35 | assert isinstance(result, list)
36 | assert all(isinstance(f, tuple) for f in result)
37 |
38 | assert ([], 'java/lang/Object[]') in result
39 | assert (['java/lang/Object[]'], 'java/lang/Object[]') in result
40 |
41 | def test_signatures(self):
42 | # >>> from jnius import autoclass
43 | # >>> cls = autoclass('java.lang.String')
44 | # >>> cls.valueOf.signatures()
45 | # [(['boolean'], 'java/lang/String'),
46 | # (['char'], 'java/lang/String'),
47 | # (['char[]'], 'java/lang/String'),
48 | # (['char[]', 'int', 'int'], 'java/lang/String'),
49 | # (['double'], 'java/lang/String'),
50 | # (['float'], 'java/lang/String'),
51 | # (['int'], 'java/lang/String'),
52 | # (['java/lang/Object'], 'java/lang/String'),
53 | # (['long'], 'java/lang/String')]
54 |
55 | cls = autoclass("java.lang.String")
56 | result = cls.valueOf.signatures()
57 |
58 | assert isinstance(result, list)
59 | assert all(isinstance(f, tuple) for f in result)
60 |
61 | assert sorted(result) == sorted([
62 | (['boolean'], 'java/lang/String'),
63 | (['char'], 'java/lang/String'),
64 | (['char[]'], 'java/lang/String'),
65 | (['char[]', 'int', 'int'], 'java/lang/String'),
66 | (['double'], 'java/lang/String'),
67 | (['float'], 'java/lang/String'),
68 | (['int'], 'java/lang/String'),
69 | (['java/lang/Object'], 'java/lang/String'),
70 | (['long'], 'java/lang/String')
71 | ])
72 |
--------------------------------------------------------------------------------
/tests/test_enum.py:
--------------------------------------------------------------------------------
1 | '''
2 | Enum in Java returns itself when trying to get a value, e.g.:
3 |
4 | SimpleEnum.GOOD
5 |
6 | is of class instance SimpleEnum.
7 |
8 | `javap -s SimpleEnum.class`::
9 |
10 | public final class org.jnius.SimpleEnum ... {
11 | public static final org.jnius.SimpleEnum GOOD;
12 | descriptor: Lorg/jnius/SimpleEnum; <-- this
13 | ...
14 | '''
15 |
16 | from __future__ import absolute_import
17 |
18 | import unittest
19 | from jnius.reflect import autoclass
20 |
21 |
22 | class TestSimpleEnum(unittest.TestCase):
23 | '''
24 | Test simple enum from java-src/org/jnius/SimpleEnum.java file.
25 | '''
26 |
27 | def test_enum(self):
28 | '''
29 | Make sure Enum returns something.
30 | '''
31 | SimpleEnum = autoclass('org.jnius.SimpleEnum')
32 | self.assertTrue(SimpleEnum)
33 |
34 | def test_value(self):
35 | '''
36 | Test whether the enum values return proper types and strings.
37 | '''
38 | SimpleEnum = autoclass('org.jnius.SimpleEnum')
39 |
40 | values = [SimpleEnum.GOOD, SimpleEnum.BAD, SimpleEnum.UGLY]
41 | for val in values:
42 | self.assertTrue(val)
43 | self.assertIsInstance(val, SimpleEnum)
44 | self.assertEqual(
45 | type(val),
46 | type(SimpleEnum.valueOf(val.toString()))
47 | )
48 |
49 | # 'GOOD', 'BAD', 'UGLY' strings
50 | self.assertEqual(
51 | val.toString(),
52 | SimpleEnum.valueOf(val.toString()).toString()
53 | )
54 |
55 | def test_value_nested(self):
56 | '''
57 | Test that we cover the circular implementation of java.lang.Enum
58 | that on value returns the parent i.e. the Enum class instead of
59 | e.g. some Exception or segfault which means we can do Enum.X.X.X...
60 |
61 | Currently does not check anything, ref pyjnius#32:
62 | https://github.com/kivy/pyjnius/issues/32.
63 | '''
64 | _ = autoclass('org.jnius.SimpleEnum')
65 | # self.assertTrue(SimpleEnum.UGLY.UGLY)
66 |
67 |
68 | if __name__ == '__main__':
69 | unittest.main()
70 |
--------------------------------------------------------------------------------
/tests/test_export_class.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | from __future__ import division
3 | from __future__ import absolute_import
4 | import unittest
5 | from jnius import autoclass, java_method, PythonJavaClass
6 |
7 | Iterable = autoclass('java.lang.Iterable')
8 | ArrayList = autoclass('java.util.ArrayList')
9 | Runnable = autoclass('java.lang.Runnable')
10 | Thread = autoclass('java.lang.Thread')
11 | Object = autoclass('java.lang.Object')
12 |
13 | class SampleIterable(PythonJavaClass):
14 | __javainterfaces__ = ['java/lang/Iterable']
15 |
16 | @java_method('()Ljava/lang/Iterator;')
17 | def iterator(self):
18 | sample = ArrayList()
19 | sample.add(1)
20 | sample.add(2)
21 | return sample.iterator()
22 |
23 | class ExportClassTest(unittest.TestCase):
24 | def test_is_instance(self):
25 | array_list = ArrayList()
26 | thread = Thread()
27 | sample_iterable = SampleIterable()
28 |
29 | self.assertIsInstance(sample_iterable, Iterable)
30 | self.assertIsInstance(sample_iterable, Object)
31 | self.assertIsInstance(sample_iterable, SampleIterable)
32 | self.assertNotIsInstance(sample_iterable, Runnable)
33 | self.assertNotIsInstance(sample_iterable, Thread)
34 |
35 | self.assertIsInstance(array_list, Iterable)
36 | self.assertIsInstance(array_list, ArrayList)
37 | self.assertIsInstance(array_list, Object)
38 |
39 | self.assertNotIsInstance(thread, Iterable)
40 | self.assertIsInstance(thread, Thread)
41 | self.assertIsInstance(thread, Runnable)
42 |
43 | def test_subclasses_work_for_arg_matching(self):
44 | array_list = ArrayList()
45 | array_list.add(SampleIterable())
46 | self.assertIsInstance(array_list.get(0), Iterable)
47 | self.assertIsInstance(array_list.get(0), SampleIterable)
48 |
49 |
50 | def assertIsSubclass(self, cls, parent):
51 | if not issubclass(cls, parent):
52 | self.fail("%s is not a subclass of %s" %
53 | (cls.__name__, parent.__name__))
54 |
55 | def assertNotIsSubclass(self, cls, parent):
56 | if issubclass(cls, parent):
57 | self.fail("%s is a subclass of %s" %
58 | (cls.__name__, parent.__name__))
59 |
60 | def test_is_subclass(self):
61 | self.assertIsSubclass(Thread, Runnable)
62 | self.assertIsSubclass(ArrayList, Iterable)
63 | self.assertIsSubclass(ArrayList, Object)
64 | self.assertIsSubclass(SampleIterable, Iterable)
65 | self.assertNotIsSubclass(Thread, Iterable)
66 | self.assertNotIsSubclass(ArrayList, Runnable)
67 | self.assertNotIsSubclass(Runnable, Thread)
68 | self.assertNotIsSubclass(Iterable, SampleIterable)
69 |
--------------------------------------------------------------------------------
/tests/test_implementation.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import print_function
3 | from __future__ import division
4 | from __future__ import absolute_import
5 | import unittest
6 | from jnius.reflect import autoclass
7 |
8 |
9 | class ImplementationTest(unittest.TestCase):
10 |
11 | def test_println(self):
12 | # System.out.println implies recursive lookup, and j_self assignation.
13 | # It was crashing during the implementation :/
14 | System = autoclass('java.lang.System')
15 | System.out.println('')
16 |
17 | def test_printf(self):
18 | System = autoclass('java.lang.System')
19 | System.out.printf('hi\n')
20 | System.out.printf('hi %s %s\n', 'jnius', 'other string')
21 |
22 | def test_unicode(self):
23 | System = autoclass('java.lang.System')
24 | System.out.printf(u'é')
25 |
26 | Stack = autoclass('java.util.Stack')
27 | stack = Stack()
28 | emoji = u'\U0001F602'
29 | stack.push(emoji)
30 | popped = stack.pop()
31 | self.assertEqual(emoji, popped)
32 |
--------------------------------------------------------------------------------
/tests/test_inheritance.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | def test_methodcalls():
4 | from jnius import autoclass
5 | Parent = autoclass('org.jnius.Parent')
6 | Child = autoclass('org.jnius.Child')
7 | child = Child.newInstance()
8 | parent = Parent.newInstance()
9 | assert parent.doCall(parent) == 0
10 | assert child.doCall(0) == 1
11 | assert child.doCall(child) == 0
12 |
13 | def test_fields():
14 | from jnius import autoclass
15 | Parent = autoclass('org.jnius.Parent')
16 | Child = autoclass('org.jnius.Child')
17 | child = Child.newInstance()
18 | parent = Parent.newInstance()
19 | assert parent.PARENT_FIELD == 0
20 | assert child.CHILD_FIELD == 1
21 | assert child.PARENT_FIELD == 0
22 |
23 | def test_staticfields():
24 | from jnius import autoclass
25 | Parent = autoclass('org.jnius.Parent')
26 | Child = autoclass('org.jnius.Child')
27 | child = Child.newInstance()
28 | parent = Parent.newInstance()
29 | assert Parent.STATIC_PARENT_FIELD == 1
30 | assert Parent.StaticGetParentStaticField() == 1
31 | assert Child.STATIC_PARENT_FIELD == 1
32 | assert Child.StaticGetParentStaticField() == 1
33 | assert parent.STATIC_PARENT_FIELD == 1
34 | assert child.STATIC_PARENT_FIELD == 1
35 | assert parent.StaticGetParentStaticField() == 1
36 | assert child.StaticGetParentStaticField() == 1
37 | assert parent.getParentStaticField() == 1
38 | assert child.getParentStaticField() == 1
39 |
40 | # now test setting in parent
41 | Parent.STATIC_PARENT_FIELD = 5
42 | assert parent.STATIC_PARENT_FIELD == 5
43 | assert Child.STATIC_PARENT_FIELD == 5
44 | assert child.STATIC_PARENT_FIELD == 5
45 | assert Parent.StaticGetParentStaticField() == 5
46 | assert Child.StaticGetParentStaticField() == 5
47 | assert parent.StaticGetParentStaticField() == 5
48 | assert child.StaticGetParentStaticField() == 5
49 | assert parent.getParentStaticField() == 5
50 | assert child.getParentStaticField() == 5
51 |
52 | # now test setting in child
53 | child.STATIC_PARENT_FIELD = 10
54 | assert Child.STATIC_PARENT_FIELD == 10
55 | assert child.STATIC_PARENT_FIELD == 10
56 | assert Parent.STATIC_PARENT_FIELD == 10
57 | assert parent.STATIC_PARENT_FIELD == 10
58 | assert Parent.StaticGetParentStaticField() == 10
59 | assert Child.StaticGetParentStaticField() == 10
60 | assert parent.StaticGetParentStaticField() == 10
61 | assert child.StaticGetParentStaticField() == 10
62 | assert parent.getParentStaticField() == 10
63 | assert child.getParentStaticField() == 10
64 |
65 | def test_newinstance():
66 | from jnius import autoclass
67 | Parent = autoclass('org.jnius.Parent')
68 | Child = autoclass('org.jnius.Child')
69 |
70 | child = Child.newInstance()
71 | assert isinstance(child, Child)
72 | assert isinstance(child, Parent)
73 |
74 | if __name__ == "__main__":
75 | import jnius_config
76 | #jnius_config.add_options('-Xcheck:jni')
77 | test_staticfields()
78 |
79 |
--------------------------------------------------------------------------------
/tests/test_int_vs_long.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import, unicode_literals
2 | import unittest
3 | from jnius import autoclass, cast, PythonJavaClass, java_method
4 |
5 |
6 | class _TestImplemIterator(PythonJavaClass):
7 | __javainterfaces__ = ['java/util/ListIterator']
8 |
9 |
10 | class _TestImplem(PythonJavaClass):
11 | __javainterfaces__ = ['java/util/List']
12 |
13 | def __init__(self, *args):
14 | super(_TestImplem, self).__init__(*args)
15 | self.data = list(args)
16 |
17 | @java_method('()I')
18 | def size(self):
19 | return len(self.data)
20 |
21 | @java_method('(I)Ljava/lang/Object;')
22 | def get(self, index):
23 | return self.data[index]
24 |
25 | @java_method('(ILjava/lang/Object;)Ljava/lang/Object;')
26 | def set(self, index, obj):
27 | old_object = self.data[index]
28 | self.data[index] = obj
29 | return old_object
30 |
31 |
32 | class TestIntLongConversion(unittest.TestCase):
33 | def test_reverse(self):
34 | '''
35 | String comparison because values are the same for INT and LONG,
36 | but only __str__ shows the real difference.
37 | '''
38 |
39 | Collections = autoclass('java.util.Collections')
40 | List = autoclass('java.util.List')
41 | pylist = list(range(10))
42 | a = _TestImplem(*pylist)
43 | self.assertEqual(a.data, pylist)
44 | self.assertEqual(str(a.data), '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]')
45 |
46 | # reverse the array, be sure it's converted back to INT!
47 | Collections.reverse(a)
48 |
49 | # conversion to/from Java objects hides INT/LONG conv on Py2
50 | # which is wrong to switch between because even Java
51 | # recognizes INT and LONG types separately (Py3 doesn't)
52 | self.assertEqual(a.data, list(reversed(pylist)))
53 | self.assertNotIn('L', str(a.data))
54 | self.assertEqual(str(a.data), '[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]')
55 |
56 |
57 | if __name__ == '__main__':
58 | unittest.main()
59 |
--------------------------------------------------------------------------------
/tests/test_interface.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | from __future__ import division
3 | from __future__ import absolute_import
4 | import unittest
5 |
6 | from jnius import autoclass, JavaException
7 |
8 |
9 | class Interface(unittest.TestCase):
10 |
11 | def test_reflect_interface(self):
12 | Interface = autoclass('org.jnius.InterfaceWithPublicEnum')
13 | self.assertTrue(Interface)
14 |
15 | def test_reflect_enum_in_interface(self):
16 | ATTITUDE = autoclass('org.jnius.InterfaceWithPublicEnum$ATTITUDE')
17 | self.assertTrue(ATTITUDE)
18 | self.assertTrue(ATTITUDE.GOOD)
19 | self.assertTrue(ATTITUDE.BAD)
20 | self.assertTrue(ATTITUDE.UGLY)
21 |
--------------------------------------------------------------------------------
/tests/test_jnitable_overflow.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | from __future__ import division
3 | from __future__ import absolute_import
4 | # run it, and check with Java VisualVM if we are eating too much memory or not!
5 | if __name__ == '__main__':
6 | from jnius import autoclass
7 | Stack = autoclass('java.util.Stack')
8 | i = 0
9 | while True:
10 | i += 1
11 | stack = Stack()
12 | stack.push('hello')
13 |
--------------------------------------------------------------------------------
/tests/test_jnius_config.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import pytest
3 | import jnius_config
4 |
5 |
6 | class TestJniusConfig:
7 | def setup_method(self):
8 | """Resets the options global."""
9 | jnius_config.options = []
10 | jnius_config.vm_running = False
11 | jnius_config.classpath = None
12 |
13 | def teardown_method(self):
14 | self.setup_method()
15 |
16 | @pytest.mark.parametrize(
17 | "function,args",
18 | [
19 | (jnius_config.set_options, ("option1",)),
20 | (jnius_config.add_options, ("option1",)),
21 | (jnius_config.set_classpath, (".",)),
22 | (jnius_config.add_classpath, (".",)),
23 | ],
24 | )
25 | def test_set_options_vm_running(self, function, args):
26 | """The functions should only raise an error when the vm is running."""
27 | assert jnius_config.vm_running is False
28 | function(*args)
29 | jnius_config.vm_running = True
30 | with pytest.raises(ValueError) as ex_info:
31 | function(*args)
32 | pytest.mark.skipif(
33 | sys.version_info < (3, 5), reason="Exception args are different on Python 2"
34 | )
35 | assert "VM is already running, can't set" in ex_info.value.args[0]
36 |
37 | def test_set_options(self):
38 | assert jnius_config.vm_running is False
39 | assert jnius_config.options == []
40 | jnius_config.set_options("option1", "option2")
41 | assert jnius_config.options == ["option1", "option2"]
42 | jnius_config.set_options("option3")
43 | assert jnius_config.options == ["option3"]
44 |
45 | def test_add_options(self):
46 | assert jnius_config.vm_running is False
47 | assert jnius_config.options == []
48 | jnius_config.add_options("option1", "option2")
49 | assert jnius_config.options == ["option1", "option2"]
50 | jnius_config.add_options("option3")
51 | assert jnius_config.options == ["option1", "option2", "option3"]
52 |
53 | def test_set_classpath(self):
54 | assert jnius_config.vm_running is False
55 | assert jnius_config.classpath is None
56 | jnius_config.set_classpath(".")
57 | assert jnius_config.classpath == ["."]
58 | jnius_config.set_classpath(".", "/usr/local/fem/plugins/*")
59 | assert jnius_config.classpath == [".", "/usr/local/fem/plugins/*"]
60 |
61 | def test_add_classpath(self):
62 | assert jnius_config.vm_running is False
63 | assert jnius_config.classpath is None
64 | jnius_config.add_classpath(".")
65 | assert jnius_config.classpath == ["."]
66 | jnius_config.add_classpath("/usr/local/fem/plugins/*")
67 | assert jnius_config.classpath == [".", "/usr/local/fem/plugins/*"]
68 |
--------------------------------------------------------------------------------
/tests/test_jvm_options.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | from __future__ import division
3 | from __future__ import absolute_import
4 | import json
5 | import pytest
6 | import subprocess
7 | import sys
8 | import textwrap
9 |
10 |
11 | class TestJVMOptions:
12 | @pytest.mark.skipif(
13 | sys.platform == 'android',
14 | reason='JNIus on Android does not take JVM options'
15 | )
16 | def test_jvm_options(self):
17 | options = ['-Dtest.var{}=value'.format(i) for i in range(40)]
18 | process = subprocess.Popen([sys.executable, '-c', textwrap.dedent(
19 | '''\
20 | import jnius_config
21 | import json
22 | import sys
23 | jnius_config.set_options(*json.load(sys.stdin))
24 | import jnius
25 | ManagementFactory = jnius.autoclass("java.lang.management.ManagementFactory")
26 | json.dump(list(ManagementFactory.getRuntimeMXBean().getInputArguments()), sys.stdout)''')],
27 | bufsize=-1, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
28 | stdoutdata, _ = process.communicate(json.dumps(options).encode())
29 | assert process.wait() == 0
30 | actual_options = json.loads(stdoutdata.decode())
31 | assert list(sorted(options)) == list(sorted(actual_options))
32 |
--------------------------------------------------------------------------------
/tests/test_lambdas.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | from jnius import autoclass, JavaException
4 |
5 | class TestLambdas(unittest.TestCase):
6 |
7 | def testCallable(self):
8 | callFn = lambda: "done"
9 | executor = autoclass("java.util.concurrent.Executors").newFixedThreadPool(1)
10 | future = executor.submit(callFn)
11 | print(type(future))
12 | self.assertEqual("done", future.get())
13 | executor.shutdownNow()
14 |
15 | def testComparator(self):
16 | numbers = autoclass('java.util.ArrayList')()
17 | Collections = autoclass('java.util.Collections')
18 | numbers.add(1)
19 | numbers.add(3)
20 | revSort = lambda i, j: j - i
21 | Collections.sort(numbers, revSort)
22 | self.assertEqual(numbers[0], 3)
23 | self.assertEqual(numbers[1], 1)
24 |
25 | def testJavaUtilFunction(self):
26 | Collectors = autoclass("java.util.stream.Collectors")
27 | numbers = autoclass('java.util.ArrayList')()
28 | numbers.add(1)
29 | numbers.add(2)
30 | numbers.add(3)
31 |
32 | def squareFn(i):
33 | return i * i
34 |
35 |
36 | #J: List squares = numbers.stream().map( i -> i*i).collect(Collectors.toList());
37 | squares = numbers.stream().map(lambda i : i * i).collect(Collectors.toList())
38 |
39 | self.assertEqual(len(squares), len(numbers))
40 | self.assertEqual(squares[0], 1)
41 | self.assertEqual(squares[1], 4)
42 | self.assertEqual(squares[2], 9)
43 |
44 | squares = numbers.stream().map(squareFn).collect(Collectors.toList())
45 |
46 | self.assertEqual(len(squares), len(numbers))
47 | self.assertEqual(squares[0], 1)
48 | self.assertEqual(squares[1], 4)
49 | self.assertEqual(squares[2], 9)
50 |
51 |
52 | if __name__ == '__main__':
53 | unittest.main()
54 |
--------------------------------------------------------------------------------
/tests/test_method_multiple_signatures.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | from __future__ import division
3 | from __future__ import absolute_import
4 | import unittest
5 | from jnius.reflect import autoclass
6 |
7 |
8 | class MultipleSignature(unittest.TestCase):
9 |
10 | def test_multiple_constructors(self):
11 | String = autoclass('java.lang.String')
12 | self.assertIsNotNone(String('Hello World'))
13 | self.assertIsNotNone(String(list('Hello World')))
14 | self.assertIsNotNone(String(list('Hello World'), 3, 5))
15 |
16 | def test_multiple_methods(self):
17 | String = autoclass('java.lang.String')
18 | s = String('hello')
19 | self.assertEqual(s.getBytes(), [104, 101, 108, 108, 111])
20 | self.assertEqual(s.getBytes('utf8'), [104, 101, 108, 108, 111])
21 | self.assertEqual(s.indexOf(ord('e')), 1)
22 | self.assertEqual(s.indexOf(ord('e'), 2), -1)
23 |
24 | def test_multiple_constructors_varargs(self):
25 | VariableArgConstructors = autoclass('org.jnius.VariableArgConstructors')
26 | c1 = VariableArgConstructors(1, 'var2', 42, None, 4)
27 | self.assertEqual(c1.constructorUsed, 1)
28 | c2 = VariableArgConstructors(1, 'var2', None, 4)
29 | self.assertEqual(c2.constructorUsed, 2)
30 |
31 | def test_multiple_methods_no_args(self):
32 | MultipleMethods = autoclass('org.jnius.MultipleMethods')
33 | self.assertEqual(MultipleMethods.resolve(), 'resolved no args')
34 |
35 | def test_multiple_methods_one_arg(self):
36 | MultipleMethods = autoclass('org.jnius.MultipleMethods')
37 | self.assertEqual(MultipleMethods.resolve('arg'), 'resolved one arg')
38 |
39 | def test_multiple_methods_two_args(self):
40 | MultipleMethods = autoclass('org.jnius.MultipleMethods')
41 | self.assertEqual(MultipleMethods.resolve('one', 'two'), 'resolved two args')
42 |
43 | def test_multiple_methods_two_string_and_an_integer(self):
44 | MultipleMethods = autoclass('org.jnius.MultipleMethods')
45 | self.assertEqual(MultipleMethods.resolve('one', 'two', 1), 'resolved two string and an integer')
46 |
47 | def test_multiple_methods_two_string_and_two_integers(self):
48 | MultipleMethods = autoclass('org.jnius.MultipleMethods')
49 | self.assertEqual(MultipleMethods.resolve('one', 'two', 1, 2), 'resolved two string and two integers')
50 |
51 | def test_multiple_methods_varargs(self):
52 | MultipleMethods = autoclass('org.jnius.MultipleMethods')
53 | self.assertEqual(MultipleMethods.resolve(1, 2, 3), 'resolved varargs')
54 |
55 | def test_multiple_methods_two_args_and_varargs(self):
56 | MultipleMethods = autoclass('org.jnius.MultipleMethods')
57 | self.assertEqual(MultipleMethods.resolve('one', 'two', 1, 2, 3), 'resolved two args and varargs')
58 |
59 | def test_multiple_methods_one_int_one_small_long_and_a_string(self):
60 | MultipleMethods = autoclass('org.jnius.MultipleMethods')
61 | self.assertEqual(MultipleMethods.resolve(
62 | 1, 1, "one"), "resolved one int, one long and a string")
63 |
64 | def test_multiple_methods_one_int_one_actual_long_and_a_string(self):
65 | MultipleMethods = autoclass('org.jnius.MultipleMethods')
66 | self.assertEqual(MultipleMethods.resolve(
67 | 1, 2 ** 63 - 1, "one"), "resolved one int, one long and a string")
68 |
--------------------------------------------------------------------------------
/tests/test_multidimension.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | from __future__ import division
3 | from __future__ import absolute_import
4 | import unittest
5 | from jnius.reflect import autoclass
6 |
7 | class MultipleDimensionsTest(unittest.TestCase):
8 |
9 | def test_multiple_dimensions(self):
10 | MultipleDims = autoclass('org.jnius.MultipleDimensions')
11 | matrix = [[1, 2, 3],
12 | [4, 5, 6],
13 | [7, 8, 9]]
14 | self.assertEqual(MultipleDims.methodParamsMatrixI(matrix), True)
15 | self.assertEqual(MultipleDims.methodReturnMatrixI(), matrix)
16 |
--------------------------------------------------------------------------------
/tests/test_object_args.py:
--------------------------------------------------------------------------------
1 | '''
2 | Check various function arguments to be properly passed to Java function
3 | as an Object that is not `null` except `None` itself.
4 | '''
5 |
6 | from __future__ import print_function
7 | from __future__ import absolute_import
8 | from __future__ import unicode_literals
9 |
10 | import unittest
11 | from jnius import autoclass, JavaException
12 |
13 |
14 | ObjectArgument = autoclass('org.jnius.ObjectArgument')
15 |
16 |
17 | class ArgumentsTest(unittest.TestCase):
18 | '''
19 | Tests for function arguments.
20 | '''
21 |
22 | def test_argument_none(self):
23 | '''
24 | Converts Python None to java.lang.Object.
25 | '''
26 | self.assertEqual(ObjectArgument.checkObject(None), -1)
27 |
28 | def test_argument_emptylist(self):
29 | '''
30 | Converts Python list to java.lang.Object.
31 | '''
32 | self.assertEqual(ObjectArgument.checkObject([]), 0)
33 |
34 | def test_argument_emptytuple(self):
35 | '''
36 | Converts Python tuple to java.lang.Object.
37 | '''
38 | self.assertEqual(ObjectArgument.checkObject(()), 0)
39 |
40 | def test_argument_list_emptylist(self):
41 | '''
42 | Converts Python list to java.lang.Object.
43 | '''
44 | self.assertEqual(ObjectArgument.checkObject([[], ]), 0)
45 |
46 | def test_argument_tuple_emptytuple(self):
47 | '''
48 | Converts Python tuple to java.lang.Object.
49 | '''
50 | self.assertEqual(ObjectArgument.checkObject(((), )), 0)
51 |
52 | def test_argument_list_none(self):
53 | '''
54 | Converts Python list to java.lang.Object.
55 | '''
56 | self.assertEqual(ObjectArgument.checkObject([None, ]), 0)
57 |
58 | def test_argument_tuple_none(self):
59 | '''
60 | Converts Python tuple to java.lang.Object.
61 | '''
62 | self.assertEqual(ObjectArgument.checkObject((None, )), 0)
63 |
64 | def test_argument_emptyunicode(self):
65 | '''
66 | Converts Python unicode to java.lang.Object.
67 | '''
68 | self.assertEqual(ObjectArgument.checkObject(u''), 0)
69 |
70 | def test_argument_emptybytes(self):
71 | '''
72 | Converts Python bytes to Java String.
73 | '''
74 | self.assertEqual(ObjectArgument.checkObject(b''), 0)
75 |
76 |
77 | if __name__ == '__main__':
78 | unittest.main()
79 |
--------------------------------------------------------------------------------
/tests/test_output_args.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | from __future__ import division
3 | from __future__ import absolute_import
4 | import unittest
5 | from jnius import autoclass
6 |
7 | class OutputArgs(unittest.TestCase):
8 |
9 | def test_string_output_args(self):
10 | String = autoclass('java.lang.String')
11 | string = String('word'.encode('utf-8'))
12 | btarray= [0] * 4
13 | string.getBytes(0, 4, btarray, 0)
14 | self.assertEqual(btarray, [119, 111, 114, 100])
15 |
--------------------------------------------------------------------------------
/tests/test_pass_by_reference_or_value.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | from __future__ import division
3 | from __future__ import absolute_import
4 | import unittest
5 | from jnius import autoclass
6 |
7 | class PassByReferenceOrValueTest(unittest.TestCase):
8 |
9 | def _verify(self, numbers, changed):
10 | for i in range(len(numbers)):
11 | self.assertEqual(numbers[i], i * i if changed else i)
12 |
13 | def _verify_all(self, numbers, changed):
14 | for n, c in zip(numbers, changed):
15 | self._verify(n, c)
16 |
17 | def test_single_param_static(self):
18 | VariablePassing = autoclass('org.jnius.VariablePassing')
19 |
20 | # passed by reference (default), numbers should change
21 | numbers = list(range(10))
22 | VariablePassing.singleParamStatic(numbers)
23 | self._verify(numbers, True)
24 |
25 | # passed by reference, numbers should change
26 | numbers = list(range(10))
27 | VariablePassing.singleParamStatic(numbers, pass_by_reference=True)
28 | self._verify(numbers, True)
29 |
30 | # passed by value, numbers should not change
31 | numbers = list(range(10))
32 | VariablePassing.singleParamStatic(numbers, pass_by_reference=False)
33 | self._verify(numbers, False)
34 |
35 | def test_single_param(self):
36 | VariablePassing = autoclass('org.jnius.VariablePassing')
37 | variablePassing = VariablePassing()
38 |
39 | # passed by reference (default), numbers should change
40 | numbers = list(range(10))
41 | variablePassing.singleParam(numbers)
42 | self._verify(numbers, True)
43 |
44 | # passed by reference, numbers should change
45 | numbers = list(range(10))
46 | variablePassing.singleParam(numbers, pass_by_reference=True)
47 | self._verify(numbers, True)
48 |
49 | # passed by value, numbers should not change
50 | numbers = list(range(10))
51 | variablePassing.singleParam(numbers, pass_by_reference=False)
52 | self._verify(numbers, False)
53 |
54 | def test_multiple_params_static(self):
55 | VariablePassing = autoclass('org.jnius.VariablePassing')
56 |
57 | # passed by reference (default), all numbers should change
58 | numbers = [list(range(10)) for _ in range(4)]
59 | VariablePassing.multipleParamsStatic(*numbers)
60 | self._verify_all(numbers, [True] * 4)
61 |
62 | # passed by reference, all numbers should change
63 | numbers = [list(range(10)) for _ in range(4)]
64 | VariablePassing.multipleParamsStatic(*numbers, pass_by_reference=True)
65 | self._verify_all(numbers, [True] * 4)
66 |
67 | # passed by value, no numbers should change
68 | numbers = [list(range(10)) for _ in range(4)]
69 | VariablePassing.multipleParamsStatic(*numbers, pass_by_reference=False)
70 | self._verify_all(numbers, [False] * 4)
71 |
72 | # only the first set of numbers should change
73 | numbers = [list(range(10)) for _ in range(4)]
74 | VariablePassing.multipleParamsStatic(*numbers, pass_by_reference=[True, False])
75 | self._verify_all(numbers, [True, False, False, False])
76 |
77 | # only the first set of numbers should not change
78 | numbers = [list(range(10)) for _ in range(4)]
79 | VariablePassing.multipleParamsStatic(*numbers, pass_by_reference=[False, True])
80 | self._verify_all(numbers, [False, True, True, True])
81 |
82 | # only the odd sets of numbers should change
83 | numbers = [list(range(10)) for _ in range(4)]
84 | changed = (True, False, True, False)
85 | VariablePassing.multipleParamsStatic(*numbers, pass_by_reference=changed)
86 | self._verify_all(numbers, changed)
87 |
88 | # only the even sets of numbers should change
89 | numbers = [list(range(10)) for _ in range(4)]
90 | changed = (False, True, False, True)
91 | VariablePassing.multipleParamsStatic(*numbers, pass_by_reference=changed)
92 | self._verify_all(numbers, changed)
93 |
94 | def test_multiple_params(self):
95 | VariablePassing = autoclass('org.jnius.VariablePassing')
96 | variablePassing = VariablePassing()
97 |
98 | # passed by reference (default), all numbers should change
99 | numbers = [list(range(10)) for _ in range(4)]
100 | variablePassing.multipleParams(*numbers)
101 | self._verify_all(numbers, [True] * 4)
102 |
103 | # passed by reference, all numbers should change
104 | numbers = [list(range(10)) for _ in range(4)]
105 | variablePassing.multipleParams(*numbers, pass_by_reference=True)
106 | self._verify_all(numbers, [True] * 4)
107 |
108 | # passed by value, no numbers should change
109 | numbers = [list(range(10)) for _ in range(4)]
110 | variablePassing.multipleParams(*numbers, pass_by_reference=False)
111 | self._verify_all(numbers, [False] * 4)
112 |
113 | # only the first set of numbers should change
114 | numbers = [list(range(10)) for _ in range(4)]
115 | variablePassing.multipleParams(*numbers, pass_by_reference=[True, False])
116 | self._verify_all(numbers, [True, False, False, False])
117 |
118 | # only the first set of numbers should not change
119 | numbers = [list(range(10)) for _ in range(4)]
120 | variablePassing.multipleParams(*numbers, pass_by_reference=[False, True])
121 | self._verify_all(numbers, [False, True, True, True])
122 |
123 | # only the odd sets of numbers should change
124 | numbers = [list(range(10)) for _ in range(4)]
125 | changed = (True, False, True, False)
126 | variablePassing.multipleParams(*numbers, pass_by_reference=changed)
127 | self._verify_all(numbers, changed)
128 |
129 | # only the even sets of numbers should change
130 | numbers = [list(range(10)) for _ in range(4)]
131 | changed = (False, True, False, True)
132 | variablePassing.multipleParams(*numbers, pass_by_reference=changed)
133 | self._verify_all(numbers, changed)
134 |
135 | def test_contructor_single_param(self):
136 | VariablePassing = autoclass('org.jnius.VariablePassing')
137 |
138 | # passed by reference (default), numbers should change
139 | numbers = list(range(10))
140 | variablePassing = VariablePassing(numbers)
141 | self._verify(numbers, True)
142 |
143 | # passed by reference, numbers should change
144 | numbers = list(range(10))
145 | variablePassing = VariablePassing(numbers, pass_by_reference=True)
146 | self._verify(numbers, True)
147 |
148 | # passed by value, numbers should not change
149 | numbers = list(range(10))
150 | variablePassing = VariablePassing(numbers, pass_by_reference=False)
151 | self._verify(numbers, False)
152 |
153 | def test_contructor_multiple_params(self):
154 | VariablePassing = autoclass('org.jnius.VariablePassing')
155 |
156 | # passed by reference (default), all numbers should change
157 | numbers = [list(range(10)) for _ in range(4)]
158 | variablePassing = VariablePassing(*numbers)
159 | self._verify_all(numbers, [True] * 4)
160 |
161 | # passed by reference, all numbers should change
162 | numbers = [list(range(10)) for _ in range(4)]
163 | variablePassing = VariablePassing(*numbers, pass_by_reference=True)
164 | self._verify_all(numbers, [True] * 4)
165 |
166 | # passed by value, no numbers should change
167 | numbers = [list(range(10)) for _ in range(4)]
168 | variablePassing = VariablePassing(*numbers, pass_by_reference=False)
169 | self._verify_all(numbers, [False] * 4)
170 |
171 | # only the first set of numbers should change
172 | numbers = [list(range(10)) for _ in range(4)]
173 | variablePassing = VariablePassing(*numbers, pass_by_reference=[True, False])
174 | self._verify_all(numbers, [True, False, False, False])
175 |
176 | # only the first set of numbers should not change
177 | numbers = [list(range(10)) for _ in range(4)]
178 | variablePassing = VariablePassing(*numbers, pass_by_reference=[False, True])
179 | self._verify_all(numbers, [False, True, True, True])
180 |
181 | # only the odd sets of numbers should change
182 | numbers = [list(range(10)) for _ in range(4)]
183 | changed = (True, False, True, False)
184 | variablePassing = VariablePassing(*numbers, pass_by_reference=changed)
185 | self._verify_all(numbers, changed)
186 |
187 | # only the even sets of numbers should change
188 | numbers = [list(range(10)) for _ in range(4)]
189 | changed = (False, True, False, True)
190 | variablePassing = VariablePassing(*numbers, pass_by_reference=changed)
191 | self._verify_all(numbers, changed)
192 |
--------------------------------------------------------------------------------
/tests/test_proxy.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | from __future__ import division
3 | from __future__ import absolute_import
4 |
5 | from jnius import autoclass, java_method, PythonJavaClass, cast
6 |
7 | print('1: declare a TestImplem that implement Collection')
8 |
9 |
10 | class _TestImplemIterator(PythonJavaClass):
11 | __javainterfaces__ = [
12 | #'java/util/Iterator',
13 | 'java/util/ListIterator', ]
14 |
15 | def __init__(self, collection, index=0):
16 | self.collection = collection
17 | self.index = index
18 |
19 | @java_method('()Z')
20 | def hasNext(self):
21 | return self.index < len(self.collection.data) - 1
22 |
23 | @java_method('()Ljava/lang/Object;')
24 | def next(self):
25 | obj = self.collection.data[self.index]
26 | self.index += 1
27 | return obj
28 |
29 | @java_method('()Z')
30 | def hasPrevious(self):
31 | return self.index >= 0
32 |
33 | @java_method('()Ljava/lang/Object;')
34 | def previous(self):
35 | self.index -= 1
36 | obj = self.collection.data[self.index]
37 | return obj
38 |
39 | @java_method('()I')
40 | def previousIndex(self):
41 | return self.index - 1
42 |
43 | @java_method('()Ljava/lang/String;')
44 | def toString(self):
45 | return repr(self)
46 |
47 | @java_method('(I)Ljava/lang/Object;')
48 | def get(self, index):
49 | return self.collection.data[index - 1]
50 |
51 | @java_method('(Ljava/lang/Object;)V')
52 | def set(self, obj):
53 | self.collection.data[self.index - 1] = obj
54 |
55 |
56 | class _TestImplem(PythonJavaClass):
57 | __javainterfaces__ = ['java/util/List']
58 |
59 | def __init__(self, *args):
60 | super(_TestImplem, self).__init__(*args)
61 | self.data = list(args)
62 |
63 | @java_method('()Ljava/util/Iterator;')
64 | def iterator(self):
65 | it = _TestImplemIterator(self)
66 | return it
67 |
68 | @java_method('()Ljava/lang/String;')
69 | def toString(self):
70 | return repr(self)
71 |
72 | @java_method('()I')
73 | def size(self):
74 | return len(self.data)
75 |
76 | @java_method('(I)Ljava/lang/Object;')
77 | def get(self, index):
78 | return self.data[index]
79 |
80 | @java_method('(ILjava/lang/Object;)Ljava/lang/Object;')
81 | def set(self, index, obj):
82 | old_object = self.data[index]
83 | self.data[index] = obj
84 | return old_object
85 |
86 | @java_method('()[Ljava/lang/Object;')
87 | def toArray(self):
88 | return self.data
89 |
90 | @java_method('()Ljava/util/ListIterator;')
91 | def listIterator(self):
92 | it = _TestImplemIterator(self)
93 | return it
94 |
95 | @java_method('(I)Ljava/util/ListIterator;',
96 | name='ListIterator')
97 | def listIteratorI(self, index):
98 | it = _TestImplemIterator(self, index)
99 | return it
100 |
101 |
102 | class _TestBadSignature(PythonJavaClass):
103 | __javainterfaces__ = ['java/util/List']
104 |
105 | @java_method('(Landroid/bluetooth/BluetoothDevice;IB[])V')
106 | def bad_signature(self, *args):
107 | pass
108 |
109 |
110 | print('2: instantiate the class, with some data')
111 | a = _TestImplem(*list(range(10)))
112 | print(a)
113 | print(dir(a))
114 |
115 | print('tries to get a ListIterator')
116 | iterator = a.listIterator()
117 | print('iterator is', iterator)
118 | while iterator.hasNext():
119 | print('at index', iterator.index, 'value is', iterator.next())
120 |
121 | print('3: Do cast to a collection')
122 | a2 = cast('java/util/Collection', a.j_self)
123 | print(a2)
124 |
125 | print('4: Try few method on the collection')
126 | Collections = autoclass('java.util.Collections')
127 | #print Collections.enumeration(a)
128 | #print Collections.enumeration(a)
129 | ret = Collections.max(a)
130 |
131 | print("reverse")
132 | print(Collections.reverse(a))
133 | print(a.data)
134 |
135 | print("before swap")
136 | print(Collections.swap(a, 2, 3))
137 | print("after swap")
138 | print(a.data)
139 |
140 | print("rotate")
141 | print(Collections.rotate(a, 5))
142 | print(a.data)
143 |
144 | print('Order of data before shuffle()', a.data)
145 | print(Collections.shuffle(a))
146 | print('Order of data after shuffle()', a.data)
147 |
148 |
149 | # XXX We have issues for methosd with multiple signature
150 | print('-> Collections.max(a)')
151 | print(Collections.max(a2))
152 | #print '-> Collections.shuffle(a)'
153 | #print Collections.shuffle(a2)
154 |
155 | # test bad signature
156 | threw = False
157 | try:
158 | _TestBadSignature()
159 | except Exception:
160 | threw = True
161 |
162 | if not threw:
163 | raise Exception("Failed to throw for bad signature")
164 |
--------------------------------------------------------------------------------
/tests/test_reflect.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | from __future__ import division
3 | from __future__ import absolute_import
4 | import unittest
5 | from jnius.reflect import autoclass
6 | from jnius import cast
7 | from jnius.reflect import identify_hierarchy
8 | from jnius import find_javaclass
9 |
10 | def identify_hierarchy_dict(cls, level, concrete=True):
11 | return({ cls.getName() : level for cls,level in identify_hierarchy(cls, level, concrete) })
12 |
13 | class ReflectTest(unittest.TestCase):
14 |
15 | def assertContains(self, d, clsName):
16 | self.assertTrue(clsName in d, clsName + " was not found in " + str(d))
17 |
18 | def test_hierharchy_queue(self):
19 | d = identify_hierarchy_dict(find_javaclass("java.util.Queue"), 0, False)
20 | self.assertContains(d, "java.util.Queue")
21 | # super interfaces
22 | self.assertContains(d, "java.util.Collection")
23 | self.assertContains(d, "java.lang.Iterable")
24 | # all instantiated interfaces are rooted at Object
25 | self.assertContains(d, "java.lang.Object")
26 | maxLevel = max(d.values())
27 | self.assertEqual(d["java.lang.Object"], maxLevel)
28 | self.assertEqual(d["java.util.Queue"], 0)
29 |
30 | def test_hierharchy_arraylist(self):
31 | d = identify_hierarchy_dict(find_javaclass("java.util.ArrayList"), 0, True)
32 | self.assertContains(d, "java.util.ArrayList")# concrete
33 | self.assertContains(d, "java.util.AbstractCollection")# superclass
34 | self.assertContains(d, "java.util.Collection")# interface
35 | self.assertContains(d, "java.lang.Iterable")# interface
36 | self.assertContains(d, "java.lang.Object")# root
37 | maxLevel = max(d.values())
38 | self.assertTrue(d["java.lang.Object"] in [maxLevel, maxLevel -1]) # Object should be pretty high up the hierarchy.
39 | self.assertEqual(d["java.util.ArrayList"], 0)
40 |
41 | def test_class(self):
42 | lstClz = autoclass("java.util.List")
43 | self.assertTrue("_class" in dir(lstClz))
44 | self.assertEqual("java.util.List", lstClz._class.getName())
45 | alstClz = autoclass("java.util.ArrayList")
46 | self.assertTrue("_class" in dir(alstClz))
47 | self.assertEqual("java.util.ArrayList", alstClz._class.getName())
48 | self.assertEqual("java.util.ArrayList", alstClz().getClass().getName())
49 |
50 | def test_stack(self):
51 | Stack = autoclass('java.util.Stack')
52 | stack = Stack()
53 | self.assertIsInstance(stack, Stack)
54 | stack.push('hello')
55 | stack.push('world')
56 | self.assertEqual(stack.pop(), 'world')
57 | self.assertEqual(stack.pop(), 'hello')
58 |
59 | def test_collection(self):
60 | HashSet = autoclass('java.util.HashSet')
61 | aset = HashSet()
62 | aset.add('hello')
63 | aset.add('world')
64 | #check that the __len__ dunder is applied to a Collection not a List
65 | self.assertEqual(2, len(aset))
66 | #check that the __len__ dunder is applied to it cast as a Collection
67 | self.assertEqual(2, len(cast("java.util.Collection", aset)))
68 |
69 | def test_list_interface(self):
70 | ArrayList = autoclass('java.util.ArrayList')
71 | words = ArrayList()
72 | words.add('hello')
73 | words.add('world')
74 | self.assertIsNotNone(words.stream())
75 | self.assertIsNotNone(words.iterator())
76 |
77 | def test_super_interface(self):
78 | LinkedList = autoclass('java.util.LinkedList')
79 | words = LinkedList()
80 | words.add('hello')
81 | words.add('world')
82 | q = cast('java.util.Queue', words)
83 | self.assertEqual(2, q.size())
84 | self.assertEqual(2, len(q))
85 | self.assertIsNotNone(q.iterator())
86 |
87 | def test_super_object(self):
88 | LinkedList = autoclass('java.util.LinkedList')
89 | words = LinkedList()
90 | words.hashCode()
91 |
92 | def test_super_interface_object(self):
93 | LinkedList = autoclass('java.util.LinkedList')
94 | words = LinkedList()
95 | q = cast('java.util.Queue', words)
96 | q.hashCode()
97 |
98 | def test_list_iteration(self):
99 | ArrayList = autoclass('java.util.ArrayList')
100 | words = ArrayList()
101 | words.add('hello')
102 | words.add('world')
103 | self.assertEqual(['hello', 'world'], [word for word in words])
104 |
105 |
--------------------------------------------------------------------------------
/tests/test_signature.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | from jnius import autoclass, java_method, PythonJavaClass, cast
4 |
5 | from jnius.signatures import *
6 |
7 | JObject = autoclass('java/lang/Object')
8 | JString = autoclass('java/lang/String')
9 | JListIterator = autoclass("java.util.ListIterator")
10 |
11 | class _TestImplemIterator(PythonJavaClass):
12 | __javainterfaces__ = [
13 | 'java/util/ListIterator', ]
14 |
15 | def __init__(self, collection, index=0):
16 | super(_TestImplemIterator, self).__init__()
17 | self.collection = collection
18 | self.index = index
19 |
20 | @with_signature(jboolean, [])
21 | def hasNext(self):
22 | return self.index < len(self.collection.data) - 1
23 |
24 | @with_signature(JObject, [])
25 | def next(self):
26 | obj = self.collection.data[self.index]
27 | self.index += 1
28 | return obj
29 |
30 | @with_signature(jboolean, [])
31 | def hasPrevious(self):
32 | return self.index >= 0
33 |
34 | @with_signature(JObject, [])
35 | def previous(self):
36 | self.index -= 1
37 | obj = self.collection.data[self.index]
38 | return obj
39 |
40 | @with_signature(jint, [])
41 | def previousIndex(self):
42 | return self.index - 1
43 |
44 | @with_signature(JString, [])
45 | def toString(self):
46 | return repr(self)
47 |
48 | @with_signature(JObject, [jint])
49 | def get(self, index):
50 | return self.collection.data[index - 1]
51 |
52 | @with_signature(jvoid, [JObject])
53 | def set(self, obj):
54 | self.collection.data[self.index - 1] = obj
55 |
56 |
57 | class _TestImplem(PythonJavaClass):
58 | __javainterfaces__ = ['java/util/List']
59 |
60 | def __init__(self, *args):
61 | super(_TestImplem, self).__init__(*args)
62 | self.data = list(args)
63 |
64 | @with_signature(autoclass("java.util.Iterator"), [])
65 | def iterator(self):
66 | it = _TestImplemIterator(self)
67 | return it
68 |
69 | @with_signature(JString, [])
70 | def toString(self):
71 | return repr(self)
72 |
73 | @with_signature(jint, [])
74 | def size(self):
75 | return len(self.data)
76 |
77 | @with_signature(JObject, [jint])
78 | def get(self, index):
79 | return self.data[index]
80 |
81 | @with_signature(JObject, [jint, JObject])
82 | def set(self, index, obj):
83 | old_object = self.data[index]
84 | self.data[index] = obj
85 | return old_object
86 |
87 | @with_signature(JArray(JObject), [])
88 | def toArray(self):
89 | return self.data
90 |
91 | @with_signature(JListIterator, [])
92 | def listIterator(self):
93 | it = _TestImplemIterator(self)
94 | return it
95 |
96 | # TODO cover this case of listIterator.
97 | @java_method(signature(JListIterator, [jint]),
98 | name='ListIterator')
99 | def listIteratorI(self, index):
100 | it = _TestImplemIterator(self, index)
101 | return it
102 |
103 |
104 | from jnius.reflect import autoclass
105 |
106 | class SignaturesTest(unittest.TestCase):
107 |
108 | def test_construct_stack_from_testimplem(self):
109 | Stack = autoclass("java.util.Stack")
110 | pyjlist = _TestImplem(1, 2, 3, 4, 5, 6, 7)
111 | stack = Stack()
112 | stack.addAll(pyjlist)
113 | self.assertEqual(7, pyjlist.size())
114 | self.assertEqual(stack.size(), pyjlist.size())
115 | array = pyjlist.toArray()
116 |
117 | def test_return_types(self):
118 |
119 | # Void
120 | sig = signature(jvoid, [])
121 | self.assertEqual(sig, "()V")
122 |
123 | # Boolean
124 | sig = signature(jboolean, [])
125 | self.assertEqual(sig, "()Z")
126 |
127 | # Byte
128 | sig = signature(jbyte, [])
129 | self.assertEqual(sig, "()B")
130 |
131 | # Char
132 | sig = signature(jchar, [])
133 | self.assertEqual(sig, "()C")
134 |
135 | # Double
136 | sig = signature(jdouble, [])
137 | self.assertEqual(sig, "()D")
138 |
139 | # Float
140 | sig = signature(jfloat, [])
141 | self.assertEqual(sig, "()F")
142 |
143 | # Int
144 | sig = signature(jint, [])
145 | self.assertEqual(sig, "()I")
146 |
147 | # Long
148 | sig = signature(jlong, [])
149 | self.assertEqual(sig, "()J")
150 |
151 | # Short
152 | sig = signature(jshort, [])
153 | self.assertEqual(sig, "()S")
154 |
155 | # Object return method
156 | String = autoclass("java.lang.String")
157 | sig = signature(String, [])
158 | self.assertEqual(sig, "()Ljava/lang/String;")
159 |
160 | # Array return
161 | sig = signature(JArray(jint), [])
162 | self.assertEqual(sig, "()[I")
163 |
164 | def test_params(self):
165 | String = autoclass("java.lang.String")
166 |
167 | # Return void, takes objects as parameters
168 | sig = signature(jvoid, [String, String])
169 | self.assertEqual(sig, "(Ljava/lang/String;Ljava/lang/String;)V")
170 |
171 | # Multiple array parameter types
172 | sig = signature(jvoid, [JArray(jint), JArray(jboolean)])
173 | self.assertEqual(sig, "([I[Z)V")
174 |
175 |
--------------------------------------------------------------------------------
/tests/test_simple.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | from __future__ import division
3 | from __future__ import absolute_import
4 | import unittest
5 | from jnius import JavaClass, MetaJavaClass, JavaMethod
6 |
7 | class HelloWorldTest(unittest.TestCase):
8 |
9 | def test_helloworld(self):
10 |
11 | class HelloWorld(JavaClass, metaclass=MetaJavaClass):
12 | __javaclass__ = 'org/jnius/HelloWorld'
13 | hello = JavaMethod('()Ljava/lang/String;')
14 |
15 | a = HelloWorld()
16 | self.assertEqual(a.hello(), 'world')
17 |
--------------------------------------------------------------------------------
/tests/test_static.py:
--------------------------------------------------------------------------------
1 | '''
2 | Test calling non-static methods on classes.
3 | '''
4 |
5 | from __future__ import absolute_import
6 | import unittest
7 | from jnius import autoclass, JavaException, JavaMethod, JavaMultipleMethod
8 |
9 |
10 | class TestStatic(unittest.TestCase):
11 |
12 | def test_method(self):
13 | '''
14 | Call a non-static JavaMethod on a class,
15 | should raise JavaException.
16 | '''
17 |
18 | String = autoclass('java.lang.String')
19 | self.assertIsInstance(String.replaceAll, JavaMethod)
20 | self.assertEqual(String('foo').replaceAll('foo', 'bar'), 'bar')
21 | with self.assertRaises(JavaException):
22 | String.replaceAll('foo', 'bar')
23 |
24 | def test_multiplemethod(self):
25 | '''
26 | Call a non-static JavaMultipleMethod on a class,
27 | should raise JavaException.
28 | '''
29 |
30 | String = autoclass('java.lang.String')
31 | self.assertIsInstance(String.toString, JavaMultipleMethod)
32 | self.assertEqual(String('baz').toString(), 'baz')
33 | with self.assertRaises(JavaException):
34 | String.toString()
35 |
36 |
37 | if __name__ == '__main__':
38 | unittest.main()
39 |
--------------------------------------------------------------------------------
/tests/test_visibility_package_protected.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | from __future__ import division
3 | from __future__ import absolute_import
4 | import unittest
5 | import jnius_config
6 | from jnius import JavaMethod, JavaStaticMethod, JavaException
7 | from jnius.reflect import autoclass
8 |
9 |
10 | class VisibilityPackageProtectedTest(unittest.TestCase):
11 | """This unittest verifies the correct visibility of package protected methods and fields.
12 |
13 | Observe that org.jnius2.ChildVisibilityTest is not in the same package as
14 | it's parent class. If `include_protected` is True and `include_private`
15 | is False, only the package protected methods and fields in the child class
16 | should be visible.
17 | """
18 |
19 | def test_child_static_fields_package_protected(self):
20 | Test = autoclass('org.jnius2.ChildVisibilityTest', include_protected=True, include_private=False)
21 |
22 | self.assertTrue(hasattr(Test, 'fieldStaticPublic'))
23 | self.assertFalse(hasattr(Test, 'fieldStaticPackageProtected'))
24 | self.assertTrue(hasattr(Test, 'fieldStaticProtected'))
25 | self.assertFalse(hasattr(Test, 'fieldStaticPrivate'))
26 |
27 | self.assertEqual(Test.fieldStaticPublic, "StaticPublic")
28 | self.assertEqual(Test.fieldStaticProtected, "StaticProtected")
29 |
30 | self.assertTrue(hasattr(Test, 'fieldChildStaticPublic'))
31 | self.assertTrue(hasattr(Test, 'fieldChildStaticPackageProtected'))
32 | self.assertTrue(hasattr(Test, 'fieldChildStaticProtected'))
33 | self.assertFalse(hasattr(Test, 'fieldChildStaticPrivate'))
34 |
35 | self.assertEqual(Test.fieldChildStaticPublic, "ChildStaticPublic")
36 | self.assertEqual(Test.fieldChildStaticPackageProtected, "ChildStaticPackageProtected")
37 | self.assertEqual(Test.fieldChildStaticProtected, "ChildStaticProtected")
38 |
39 | def test_child_static_methods_package_protected(self):
40 | Test = autoclass('org.jnius2.ChildVisibilityTest', include_protected=True, include_private=False)
41 |
42 | self.assertTrue(hasattr(Test, 'methodStaticPublic'))
43 | self.assertFalse(hasattr(Test, 'methodStaticPackageProtected'))
44 | self.assertTrue(hasattr(Test, 'methodStaticProtected'))
45 | self.assertFalse(hasattr(Test, 'methodStaticPrivate'))
46 |
47 | self.assertEqual(Test.methodStaticPublic(), "StaticPublic")
48 | self.assertEqual(Test.methodStaticProtected(), "StaticProtected")
49 |
50 | self.assertTrue(hasattr(Test, 'methodChildStaticPublic'))
51 | self.assertTrue(hasattr(Test, 'methodChildStaticPackageProtected'))
52 | self.assertTrue(hasattr(Test, 'methodChildStaticProtected'))
53 | self.assertFalse(hasattr(Test, 'methodChildStaticPrivate'))
54 |
55 | self.assertEqual(Test.methodChildStaticPublic(), "ChildStaticPublic")
56 | self.assertEqual(Test.methodChildStaticPackageProtected(), "ChildStaticPackageProtected")
57 | self.assertEqual(Test.methodChildStaticProtected(), "ChildStaticProtected")
58 |
59 | def test_child_fields_package_protected(self):
60 |
61 | Test = autoclass('org.jnius2.ChildVisibilityTest', include_protected=True, include_private=False)
62 | test = Test()
63 |
64 | self.assertTrue(hasattr(test, 'fieldPublic'))
65 | self.assertFalse(hasattr(test, 'fieldPackageProtected'))
66 | self.assertTrue(hasattr(test, 'fieldProtected'))
67 | self.assertFalse(hasattr(test, 'fieldPrivate'))
68 |
69 | self.assertEqual(test.fieldPublic, "Public")
70 | self.assertEqual(test.fieldProtected, "Protected")
71 |
72 | self.assertTrue(hasattr(test, 'fieldChildPublic'))
73 | self.assertTrue(hasattr(test, 'fieldChildPackageProtected'))
74 | self.assertTrue(hasattr(test, 'fieldChildProtected'))
75 | self.assertFalse(hasattr(test, 'fieldChildPrivate'))
76 |
77 | self.assertEqual(test.fieldChildPublic, "ChildPublic")
78 | self.assertEqual(test.fieldChildPackageProtected, "ChildPackageProtected")
79 | self.assertEqual(test.fieldChildProtected, "ChildProtected")
80 |
81 | def test_child_methods_package_protected(self):
82 |
83 | Test = autoclass('org.jnius2.ChildVisibilityTest', include_protected=True, include_private=False)
84 | test = Test()
85 |
86 | self.assertTrue(hasattr(test, 'methodPublic'))
87 | self.assertFalse(hasattr(test, 'methodPackageProtected'))
88 | self.assertTrue(hasattr(test, 'methodProtected'))
89 | self.assertFalse(hasattr(test, 'methodPrivate'))
90 |
91 | self.assertEqual(test.methodPublic(), "Public")
92 | self.assertEqual(test.methodProtected(), "Protected")
93 |
94 | self.assertTrue(hasattr(test, 'methodChildPublic'))
95 | self.assertTrue(hasattr(test, 'methodChildPackageProtected'))
96 | self.assertTrue(hasattr(test, 'methodChildProtected'))
97 | self.assertFalse(hasattr(test, 'methodChildPrivate'))
98 |
99 | self.assertEqual(test.methodChildPublic(), "ChildPublic")
100 | self.assertEqual(test.methodChildPackageProtected(), "ChildPackageProtected")
101 | self.assertEqual(test.methodChildProtected(), "ChildProtected")
102 |
--------------------------------------------------------------------------------
/tests/test_visibility_public_only.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | from __future__ import division
3 | from __future__ import absolute_import
4 | import unittest
5 | import jnius_config
6 | from jnius import JavaMethod, JavaStaticMethod, JavaException
7 | from jnius.reflect import autoclass
8 |
9 |
10 | class VisibilityPublicOnlyTest(unittest.TestCase):
11 |
12 | def test_static_fields_public_only(self):
13 | Test = autoclass('org.jnius.VisibilityTest', include_protected=False, include_private=False)
14 |
15 | self.assertTrue(hasattr(Test, 'fieldStaticPublic'))
16 | self.assertFalse(hasattr(Test, 'fieldStaticPackageProtected'))
17 | self.assertFalse(hasattr(Test, 'fieldStaticProtected'))
18 | self.assertFalse(hasattr(Test, 'fieldStaticPrivate'))
19 |
20 | self.assertEqual(Test.fieldStaticPublic, "StaticPublic")
21 |
22 | def test_child_static_fields_public_only(self):
23 | Test = autoclass('org.jnius.ChildVisibilityTest', include_protected=False, include_private=False)
24 |
25 | self.assertTrue(hasattr(Test, 'fieldStaticPublic'))
26 | self.assertFalse(hasattr(Test, 'fieldStaticPackageProtected'))
27 | self.assertFalse(hasattr(Test, 'fieldStaticProtected'))
28 | self.assertFalse(hasattr(Test, 'fieldStaticPrivate'))
29 |
30 | self.assertEqual(Test.fieldStaticPublic, "StaticPublic")
31 |
32 | self.assertTrue(hasattr(Test, 'fieldChildStaticPublic'))
33 | self.assertFalse(hasattr(Test, 'fieldChildStaticPackageProtected'))
34 | self.assertFalse(hasattr(Test, 'fieldChildStaticProtected'))
35 | self.assertFalse(hasattr(Test, 'fieldChildStaticPrivate'))
36 |
37 | self.assertEqual(Test.fieldChildStaticPublic, "ChildStaticPublic")
38 |
39 | def test_static_methods_public_only(self):
40 | Test = autoclass('org.jnius.VisibilityTest', include_protected=False, include_private=False)
41 |
42 | self.assertTrue(hasattr(Test, 'methodStaticPublic'))
43 | self.assertFalse(hasattr(Test, 'methodStaticPackageProtected'))
44 | self.assertFalse(hasattr(Test, 'methodStaticProtected'))
45 | self.assertFalse(hasattr(Test, 'methodStaticPrivate'))
46 |
47 | self.assertEqual(Test.methodStaticPublic(), "StaticPublic")
48 |
49 | def test_child_static_methods_public_only(self):
50 | Test = autoclass('org.jnius.ChildVisibilityTest', include_protected=False, include_private=False)
51 |
52 | self.assertTrue(hasattr(Test, 'methodStaticPublic'))
53 | self.assertFalse(hasattr(Test, 'methodStaticPackageProtected'))
54 | self.assertFalse(hasattr(Test, 'methodStaticProtected'))
55 | self.assertFalse(hasattr(Test, 'methodStaticPrivate'))
56 |
57 | self.assertEqual(Test.methodStaticPublic(), "StaticPublic")
58 |
59 | self.assertTrue(hasattr(Test, 'methodChildStaticPublic'))
60 | self.assertFalse(hasattr(Test, 'methodChildStaticPackageProtected'))
61 | self.assertFalse(hasattr(Test, 'methodChildStaticProtected'))
62 | self.assertFalse(hasattr(Test, 'methodChildStaticPrivate'))
63 |
64 | self.assertEqual(Test.methodChildStaticPublic(), "ChildStaticPublic")
65 |
66 | def test_fields_public_only(self):
67 |
68 | Test = autoclass('org.jnius.VisibilityTest', include_protected=False, include_private=False)
69 | test = Test()
70 |
71 | self.assertTrue(hasattr(test, 'fieldPublic'))
72 | self.assertFalse(hasattr(test, 'fieldPackageProtected'))
73 | self.assertFalse(hasattr(test, 'fieldProtected'))
74 | self.assertFalse(hasattr(test, 'fieldPrivate'))
75 |
76 | self.assertEqual(test.fieldPublic, "Public")
77 |
78 | def test_child_fields_public_only(self):
79 |
80 | Test = autoclass('org.jnius.ChildVisibilityTest', include_protected=False, include_private=False)
81 | test = Test()
82 |
83 | self.assertTrue(hasattr(test, 'fieldPublic'))
84 | self.assertFalse(hasattr(test, 'fieldPackageProtected'))
85 | self.assertFalse(hasattr(test, 'fieldProtected'))
86 | self.assertFalse(hasattr(test, 'fieldPrivate'))
87 |
88 | self.assertEqual(test.fieldPublic, "Public")
89 |
90 | self.assertTrue(hasattr(test, 'fieldChildPublic'))
91 | self.assertFalse(hasattr(test, 'fieldChildPackageProtected'))
92 | self.assertFalse(hasattr(test, 'fieldChildProtected'))
93 | self.assertFalse(hasattr(test, 'fieldChildPrivate'))
94 |
95 | self.assertEqual(test.fieldChildPublic, "ChildPublic")
96 |
97 | def test_methods_public_only(self):
98 |
99 | Test = autoclass('org.jnius.VisibilityTest', include_protected=False, include_private=False)
100 | test = Test()
101 |
102 | self.assertTrue(hasattr(test, 'methodPublic'))
103 | self.assertFalse(hasattr(test, 'methodPackageProtected'))
104 | self.assertFalse(hasattr(test, 'methodProtected'))
105 | self.assertFalse(hasattr(test, 'methodPrivate'))
106 |
107 | self.assertEqual(test.methodPublic(), "Public")
108 |
109 | def test_child_methods_public_only(self):
110 |
111 | Test = autoclass('org.jnius.ChildVisibilityTest', include_protected=False, include_private=False)
112 | test = Test()
113 |
114 | self.assertTrue(hasattr(test, 'methodPublic'))
115 | self.assertFalse(hasattr(test, 'methodPackageProtected'))
116 | self.assertFalse(hasattr(test, 'methodProtected'))
117 | self.assertFalse(hasattr(test, 'methodPrivate'))
118 |
119 | self.assertEqual(test.methodPublic(), "Public")
120 |
121 | self.assertTrue(hasattr(test, 'methodChildPublic'))
122 | self.assertFalse(hasattr(test, 'methodChildPackageProtected'))
123 | self.assertFalse(hasattr(test, 'methodChildProtected'))
124 | self.assertFalse(hasattr(test, 'methodChildPrivate'))
125 |
126 | self.assertEqual(test.methodChildPublic(), "ChildPublic")
127 |
128 | def test_static_multi_methods(self):
129 | Test = autoclass('org.jnius.ChildVisibilityTest', include_protected=False, include_private=False)
130 |
131 | self.assertTrue(hasattr(Test, 'methodStaticMultiArgs'))
132 | self.assertTrue(isinstance(Test.methodStaticMultiArgs, JavaStaticMethod))
133 |
134 | self.assertTrue(Test.methodStaticMultiArgs(True))
135 | with self.assertRaises(JavaException):
136 | Test.methodStaticMultiArgs(True, False)
137 | with self.assertRaises(JavaException):
138 | Test.methodStaticMultiArgs(True, False, True)
139 |
140 | def test_multi_methods(self):
141 | Test = autoclass('org.jnius.ChildVisibilityTest', include_protected=False, include_private=False)
142 | test = Test()
143 |
144 | self.assertTrue(hasattr(test, 'methodMultiArgs'))
145 | self.assertTrue(isinstance(Test.methodMultiArgs, JavaMethod))
146 |
147 | self.assertTrue(test.methodMultiArgs(True))
148 | with self.assertRaises(JavaException):
149 | test.methodMultiArgs(True, False)
150 | with self.assertRaises(JavaException):
151 | test.methodMultiArgs(True, False, True)
152 |
--------------------------------------------------------------------------------
/tests/test_visibility_public_protected.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | from __future__ import division
3 | from __future__ import absolute_import
4 | import unittest
5 | import jnius_config
6 | from jnius import JavaMultipleMethod, JavaException
7 | from jnius.reflect import autoclass
8 |
9 |
10 | class VisibilityPublicProtectedTest(unittest.TestCase):
11 |
12 | def test_static_fields_public_protected(self):
13 | Test = autoclass('org.jnius.VisibilityTest', include_protected=True, include_private=False)
14 |
15 | self.assertTrue(hasattr(Test, 'fieldStaticPublic'))
16 | self.assertTrue(hasattr(Test, 'fieldStaticPackageProtected'))
17 | self.assertTrue(hasattr(Test, 'fieldStaticProtected'))
18 | self.assertFalse(hasattr(Test, 'fieldStaticPrivate'))
19 |
20 | self.assertEqual(Test.fieldStaticPublic, "StaticPublic")
21 | self.assertEqual(Test.fieldStaticPackageProtected, "StaticPackageProtected")
22 | self.assertEqual(Test.fieldStaticProtected, "StaticProtected")
23 |
24 | def test_child_static_fields_public_protected(self):
25 | Test = autoclass('org.jnius.ChildVisibilityTest', include_protected=True, include_private=False)
26 |
27 | self.assertTrue(hasattr(Test, 'fieldStaticPublic'))
28 | self.assertTrue(hasattr(Test, 'fieldStaticPackageProtected'))
29 | self.assertTrue(hasattr(Test, 'fieldStaticProtected'))
30 | self.assertFalse(hasattr(Test, 'fieldStaticPrivate'))
31 |
32 | self.assertEqual(Test.fieldStaticPublic, "StaticPublic")
33 | self.assertEqual(Test.fieldStaticPackageProtected, "StaticPackageProtected")
34 | self.assertEqual(Test.fieldStaticProtected, "StaticProtected")
35 |
36 | self.assertTrue(hasattr(Test, 'fieldChildStaticPublic'))
37 | self.assertTrue(hasattr(Test, 'fieldChildStaticPackageProtected'))
38 | self.assertTrue(hasattr(Test, 'fieldChildStaticProtected'))
39 | self.assertFalse(hasattr(Test, 'fieldChildStaticPrivate'))
40 |
41 | self.assertEqual(Test.fieldChildStaticPublic, "ChildStaticPublic")
42 | self.assertEqual(Test.fieldChildStaticPackageProtected, "ChildStaticPackageProtected")
43 | self.assertEqual(Test.fieldChildStaticProtected, "ChildStaticProtected")
44 |
45 | def test_static_methods_public_protected(self):
46 | Test = autoclass('org.jnius.VisibilityTest', include_protected=True, include_private=False)
47 |
48 | self.assertTrue(hasattr(Test, 'methodStaticPublic'))
49 | self.assertTrue(hasattr(Test, 'methodStaticPackageProtected'))
50 | self.assertTrue(hasattr(Test, 'methodStaticProtected'))
51 | self.assertFalse(hasattr(Test, 'methodStaticPrivate'))
52 |
53 | self.assertEqual(Test.methodStaticPublic(), "StaticPublic")
54 | self.assertEqual(Test.methodStaticPackageProtected(), "StaticPackageProtected")
55 | self.assertEqual(Test.methodStaticProtected(), "StaticProtected")
56 |
57 | def test_child_static_methods_public_protected(self):
58 | Test = autoclass('org.jnius.ChildVisibilityTest', include_protected=True, include_private=False)
59 |
60 | self.assertTrue(hasattr(Test, 'methodStaticPublic'))
61 | self.assertTrue(hasattr(Test, 'methodStaticPackageProtected'))
62 | self.assertTrue(hasattr(Test, 'methodStaticProtected'))
63 | self.assertFalse(hasattr(Test, 'methodStaticPrivate'))
64 |
65 | self.assertEqual(Test.methodStaticPublic(), "StaticPublic")
66 | self.assertEqual(Test.methodStaticPackageProtected(), "StaticPackageProtected")
67 | self.assertEqual(Test.methodStaticProtected(), "StaticProtected")
68 |
69 | self.assertTrue(hasattr(Test, 'methodChildStaticPublic'))
70 | self.assertTrue(hasattr(Test, 'methodChildStaticPackageProtected'))
71 | self.assertTrue(hasattr(Test, 'methodChildStaticProtected'))
72 | self.assertFalse(hasattr(Test, 'methodChildStaticPrivate'))
73 |
74 | self.assertEqual(Test.methodChildStaticPublic(), "ChildStaticPublic")
75 | self.assertEqual(Test.methodChildStaticPackageProtected(), "ChildStaticPackageProtected")
76 | self.assertEqual(Test.methodChildStaticProtected(), "ChildStaticProtected")
77 |
78 | def test_fields_public_protected(self):
79 |
80 | Test = autoclass('org.jnius.VisibilityTest', include_protected=True, include_private=False)
81 | test = Test()
82 |
83 | self.assertTrue(hasattr(test, 'fieldPublic'))
84 | self.assertTrue(hasattr(test, 'fieldPackageProtected'))
85 | self.assertTrue(hasattr(test, 'fieldProtected'))
86 | self.assertFalse(hasattr(test, 'fieldPrivate'))
87 |
88 | self.assertEqual(test.fieldPublic, "Public")
89 | self.assertEqual(test.fieldPackageProtected, "PackageProtected")
90 | self.assertEqual(test.fieldProtected, "Protected")
91 |
92 | def test_child_fields_public_protected(self):
93 |
94 | Test = autoclass('org.jnius.ChildVisibilityTest', include_protected=True, include_private=False)
95 | test = Test()
96 |
97 | self.assertTrue(hasattr(test, 'fieldPublic'))
98 | self.assertTrue(hasattr(test, 'fieldPackageProtected'))
99 | self.assertTrue(hasattr(test, 'fieldProtected'))
100 | self.assertFalse(hasattr(test, 'fieldPrivate'))
101 |
102 | self.assertEqual(test.fieldPublic, "Public")
103 | self.assertEqual(test.fieldPackageProtected, "PackageProtected")
104 | self.assertEqual(test.fieldProtected, "Protected")
105 |
106 | self.assertTrue(hasattr(test, 'fieldChildPublic'))
107 | self.assertTrue(hasattr(test, 'fieldChildPackageProtected'))
108 | self.assertTrue(hasattr(test, 'fieldChildProtected'))
109 | self.assertFalse(hasattr(test, 'fieldChildPrivate'))
110 |
111 | self.assertEqual(test.fieldChildPublic, "ChildPublic")
112 | self.assertEqual(test.fieldChildPackageProtected, "ChildPackageProtected")
113 | self.assertEqual(test.fieldChildProtected, "ChildProtected")
114 |
115 | def test_methods_public_protected(self):
116 |
117 | Test = autoclass('org.jnius.VisibilityTest', include_protected=True, include_private=False)
118 | test = Test()
119 |
120 | self.assertTrue(hasattr(test, 'methodPublic'))
121 | self.assertTrue(hasattr(test, 'methodPackageProtected'))
122 | self.assertTrue(hasattr(test, 'methodProtected'))
123 | self.assertFalse(hasattr(test, 'methodPrivate'))
124 |
125 | self.assertEqual(test.methodPublic(), "Public")
126 | self.assertEqual(test.methodPackageProtected(), "PackageProtected")
127 | self.assertEqual(test.methodProtected(), "Protected")
128 |
129 | def test_child_methods_public_protected(self):
130 |
131 | Test = autoclass('org.jnius.ChildVisibilityTest', include_protected=True, include_private=False)
132 | test = Test()
133 |
134 | self.assertTrue(hasattr(test, 'methodPublic'))
135 | self.assertTrue(hasattr(test, 'methodPackageProtected'))
136 | self.assertTrue(hasattr(test, 'methodProtected'))
137 | self.assertFalse(hasattr(test, 'methodPrivate'))
138 |
139 | self.assertEqual(test.methodPublic(), "Public")
140 | self.assertEqual(test.methodPackageProtected(), "PackageProtected")
141 | self.assertEqual(test.methodProtected(), "Protected")
142 |
143 | self.assertTrue(hasattr(test, 'methodChildPublic'))
144 | self.assertTrue(hasattr(test, 'methodChildPackageProtected'))
145 | self.assertTrue(hasattr(test, 'methodChildProtected'))
146 | self.assertFalse(hasattr(test, 'methodChildPrivate'))
147 |
148 | self.assertEqual(test.methodChildPublic(), "ChildPublic")
149 | self.assertEqual(test.methodChildPackageProtected(), "ChildPackageProtected")
150 | self.assertEqual(test.methodChildProtected(), "ChildProtected")
151 |
152 | def test_static_multi_methods(self):
153 | Test = autoclass('org.jnius.ChildVisibilityTest', include_protected=True, include_private=False)
154 |
155 | self.assertTrue(hasattr(Test, 'methodStaticMultiArgs'))
156 | self.assertTrue(isinstance(Test.methodStaticMultiArgs, JavaMultipleMethod))
157 |
158 | self.assertTrue(Test.methodStaticMultiArgs(True))
159 | self.assertTrue(Test.methodStaticMultiArgs(True, False))
160 | with self.assertRaises(JavaException):
161 | Test.methodStaticMultiArgs(True, False, True)
162 |
163 | def test_multi_methods(self):
164 | Test = autoclass('org.jnius.ChildVisibilityTest', include_protected=True, include_private=False)
165 | test = Test()
166 |
167 | self.assertTrue(hasattr(test, 'methodMultiArgs'))
168 | self.assertTrue(isinstance(Test.methodMultiArgs, JavaMultipleMethod))
169 |
170 | self.assertTrue(test.methodMultiArgs(True))
171 | self.assertTrue(test.methodMultiArgs(True, False))
172 | with self.assertRaises(JavaException):
173 | test.methodMultiArgs(True, False, True)
174 |
--------------------------------------------------------------------------------