mirror of
https://github.com/go-i2p/gojava.git
synced 2025-06-16 05:44:42 -04:00
Initial commit with a working build.
Some of the tests are failing.
This commit is contained in:
178
.gitignore
vendored
Normal file
178
.gitignore
vendored
Normal file
@ -0,0 +1,178 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
|
||||
*.swp
|
||||
|
||||
.idea
|
||||
*.iml
|
||||
|
||||
node_modules
|
||||
out
|
||||
tutorials
|
||||
.DS_Store
|
||||
|
||||
*.xcuserstate
|
||||
project.xcworkspace/
|
||||
|
||||
.Trashes
|
||||
|
||||
*~.nib
|
||||
DerivedData/
|
||||
build/
|
||||
|
||||
/vendor/
|
||||
|
||||
*.pbxuser
|
||||
|
||||
# .mode1v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html
|
||||
|
||||
*.mode1v3
|
||||
|
||||
# .mode2v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html
|
||||
|
||||
*.mode2v3
|
||||
|
||||
# .perspectivev3: http://stackoverflow.com/questions/5223297/xcode-projects-what-is-a-perspectivev3-file
|
||||
|
||||
*.perspectivev3
|
||||
|
||||
# NB: also, whitelist the default ones, some projects need to use these
|
||||
!default.pbxuser
|
||||
!default.mode1v3
|
||||
!default.mode2v3
|
||||
!default.perspectivev3
|
||||
|
||||
|
||||
####
|
||||
# Xcode 4 - semi-personal settings
|
||||
#
|
||||
# Apple Shared data that Apple put in the wrong folder
|
||||
# c.f. http://stackoverflow.com/a/19260712/153422
|
||||
# FROM ANSWER: Apple says "don't ignore it"
|
||||
# FROM COMMENTS: Apple is wrong; Apple code is too buggy to trust; there are no known negative side-effects to ignoring Apple's unofficial advice and instead doing the thing that actively fixes bugs in Xcode
|
||||
# Up to you, but ... current advice: ignore it.
|
||||
*.xccheckout
|
||||
|
||||
#
|
||||
#
|
||||
# OPTION 1: ---------------------------------
|
||||
# throw away ALL personal settings (including custom schemes!
|
||||
# - unless they are "shared")
|
||||
# As per build/ and DerivedData/, this ought to have a trailing slash
|
||||
#
|
||||
# NB: this is exclusive with OPTION 2 below
|
||||
xcuserdata/
|
||||
|
||||
# OPTION 2: ---------------------------------
|
||||
# get rid of ALL personal settings, but KEEP SOME OF THEM
|
||||
# - NB: you must manually uncomment the bits you want to keep
|
||||
#
|
||||
# NB: this *requires* git v1.8.2 or above; you may need to upgrade to latest OS X,
|
||||
# or manually install git over the top of the OS X version
|
||||
# NB: this is exclusive with OPTION 1 above
|
||||
#
|
||||
#xcuserdata/**/*
|
||||
|
||||
# (requires option 2 above): Personal Schemes
|
||||
#
|
||||
#!xcuserdata/**/xcschemes/*
|
||||
|
||||
####
|
||||
# XCode 4 workspaces - more detailed
|
||||
#
|
||||
# Workspaces are important! They are a core feature of Xcode - don't exclude them :)
|
||||
#
|
||||
# Workspace layout is quite spammy. For reference:
|
||||
#
|
||||
# /(root)/
|
||||
# /(project-name).xcodeproj/
|
||||
# project.pbxproj
|
||||
# /project.xcworkspace/
|
||||
# contents.xcworkspacedata
|
||||
# /xcuserdata/
|
||||
# /(your name)/xcuserdatad/
|
||||
# UserInterfaceState.xcuserstate
|
||||
# /xcshareddata/
|
||||
# /xcschemes/
|
||||
# (shared scheme name).xcscheme
|
||||
# /xcuserdata/
|
||||
# /(your name)/xcuserdatad/
|
||||
# (private scheme).xcscheme
|
||||
# xcschememanagement.plist
|
||||
#
|
||||
#
|
||||
|
||||
####
|
||||
# Xcode 4 - Deprecated classes
|
||||
#
|
||||
# Allegedly, if you manually "deprecate" your classes, they get moved here.
|
||||
#
|
||||
# We're using source-control, so this is a "feature" that we do not want!
|
||||
|
||||
*.moved-aside
|
||||
|
||||
#
|
||||
# COCOAPODS:
|
||||
#
|
||||
# c.f. http://guides.cocoapods.org/using/using-cocoapods.html#what-is-a-podfilelock
|
||||
# c.f. http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
|
||||
|
||||
!Podfile.lock
|
||||
|
||||
# Android
|
||||
#
|
||||
# Built application files
|
||||
*.apk
|
||||
*.ap_
|
||||
|
||||
# Files for the Dalvik VM
|
||||
*.dex
|
||||
|
||||
# Java class files
|
||||
*.class
|
||||
|
||||
# Generated files
|
||||
bin/
|
||||
gen/
|
||||
|
||||
# Gradle files
|
||||
.gradle/
|
||||
build/
|
||||
|
||||
# Local configuration file (sdk path, etc)
|
||||
local.properties
|
||||
|
||||
# Proguard folder generated by Eclipse
|
||||
proguard/
|
||||
|
||||
# Log Files
|
||||
*.log
|
||||
|
||||
# Android Studio Navigation editor temp files
|
||||
.navigation/
|
||||
|
||||
# Android Studio captures folder
|
||||
captures/
|
||||
|
201
LICENSE
Normal file
201
LICENSE
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2016 Sridhar Venkatakrishnan
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
39
LoadJNI.java
Normal file
39
LoadJNI.java
Normal file
@ -0,0 +1,39 @@
|
||||
package go;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class LoadJNI {
|
||||
static {
|
||||
try {
|
||||
loadLibrary();
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static void loadLibrary() throws IOException {
|
||||
File temp = File.createTempFile("gojava", "gojava");
|
||||
temp.deleteOnExit();
|
||||
|
||||
InputStream input = LoadJNI.class.getResourceAsStream("/go/libgojava");
|
||||
if (input == null) {
|
||||
throw new RuntimeException("Go JNI library not found in classpath");
|
||||
}
|
||||
OutputStream out = new FileOutputStream(temp);
|
||||
try {
|
||||
byte[] buffer = new byte[1024];
|
||||
int readBytes = 0;
|
||||
while ((readBytes = input.read(buffer)) != -1) {
|
||||
out.write(buffer, 0, readBytes);
|
||||
}
|
||||
} finally {
|
||||
out.close();
|
||||
input.close();
|
||||
}
|
||||
System.load(temp.getAbsolutePath());
|
||||
}
|
||||
}
|
85
MoreAsserts.java
Normal file
85
MoreAsserts.java
Normal file
@ -0,0 +1,85 @@
|
||||
package go;
|
||||
|
||||
import go.LoadJNI;
|
||||
import java.util.Arrays;
|
||||
import java.lang.Math;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import go.SeqTest;
|
||||
|
||||
public class MoreAsserts {
|
||||
public static void assertTrue(String msg, boolean condition) {
|
||||
if (!condition) {
|
||||
throw new RuntimeException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void assertTrue(boolean condition) {
|
||||
if (!condition) {
|
||||
throw new RuntimeException("assert failed");
|
||||
}
|
||||
}
|
||||
|
||||
public static void assertEquals(int expected, int actual) {
|
||||
assertTrue(expected == actual);
|
||||
}
|
||||
|
||||
public static void assertFalse(boolean condition) {
|
||||
assertTrue(!condition);
|
||||
}
|
||||
|
||||
public static void assertFalse(String msg, boolean condition) {
|
||||
assertTrue(msg, !condition);
|
||||
}
|
||||
|
||||
public static void assertEquals(String msg, int expected, int actual) {
|
||||
assertTrue(msg, expected == actual);
|
||||
}
|
||||
|
||||
public static void assertEquals(String msg, long expected, long actual) {
|
||||
assertTrue(msg, expected == actual);
|
||||
}
|
||||
|
||||
public static void assertEquals(String msg, String expected, String actual) {
|
||||
assertTrue(msg, expected == actual);
|
||||
}
|
||||
|
||||
public static void assertEquals(String msg, boolean expected, boolean actual) {
|
||||
assertTrue(msg, expected == actual);
|
||||
}
|
||||
public static void assertEquals(String msg, byte[] expected, byte[] actual) {
|
||||
assertTrue(msg, Arrays.equals(expected, actual));
|
||||
}
|
||||
|
||||
public static void assertEquals(String msg, double expected, double actual, double epsilon) {
|
||||
assertTrue(msg, Math.abs(expected - actual) < epsilon);
|
||||
}
|
||||
|
||||
public static void assertEquals(String msg, Object expected, Object actual) {
|
||||
assertTrue(msg, (expected == null && actual == null) || (expected.equals(actual)));
|
||||
}
|
||||
|
||||
public static void fail(String msg) {
|
||||
throw new RuntimeException(msg);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SeqTest test = new SeqTest();
|
||||
Class c = test.getClass();
|
||||
for (Method method : c.getDeclaredMethods()) {
|
||||
if (!method.getName().startsWith("test")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
System.out.print(method.getName());
|
||||
try {
|
||||
method.invoke(test);
|
||||
System.out.println(" PASS");
|
||||
} catch (Exception ex) {
|
||||
System.out.println(" FAIL");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
4
README.md
Normal file
4
README.md
Normal file
@ -0,0 +1,4 @@
|
||||
## GoJava - gobind for java
|
||||
|
||||
WIP: This doesn't work yet
|
||||
|
258
gojava.go
Normal file
258
gojava.go
Normal file
@ -0,0 +1,258 @@
|
||||
package gojava
|
||||
|
||||
import (
|
||||
"go/build"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
|
||||
"fmt"
|
||||
"go/importer"
|
||||
"go/token"
|
||||
"go/types"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"io/ioutil"
|
||||
|
||||
"archive/zip"
|
||||
"runtime"
|
||||
|
||||
"github.com/sridharv/gomobile-java/bind"
|
||||
)
|
||||
|
||||
func runCommandWithEnv(env []string, cmd string, args ...string) error {
|
||||
c := exec.Command(cmd, args...)
|
||||
c.Env = append(os.Environ(), env...)
|
||||
out, err := c.CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s %s %s: %v: %s", strings.Join(env, " "), cmd, strings.Join(args, " "), err, string(out))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func runCommand(cmd string, args ...string) error {
|
||||
return runCommandWithEnv([]string{}, cmd, args...)
|
||||
}
|
||||
|
||||
func createJar(target string, pkgs ...string) error {
|
||||
javaHome := os.Getenv("JAVA_HOME")
|
||||
if javaHome == "" {
|
||||
return fmt.Errorf("$JAVA_HOME not set")
|
||||
}
|
||||
tmpDir, err := ioutil.TempDir("", "gojava")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// Load export data for the packages
|
||||
if err := runCommand("go", append([]string{"install"}, pkgs...)...); err != nil {
|
||||
return err
|
||||
}
|
||||
typePkgs := make([]*types.Package, len(pkgs))
|
||||
|
||||
for i, p := range pkgs {
|
||||
var err error
|
||||
if typePkgs[i], err = importer.Default().Import(p); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
bindDir := filepath.Join(tmpDir, "gojava_bind")
|
||||
mainDir := filepath.Join(bindDir, "main")
|
||||
mainFile := filepath.Join(mainDir, "main.go")
|
||||
javaDir := filepath.Join(tmpDir, "src/go")
|
||||
classDir := filepath.Join(tmpDir, "classes/go")
|
||||
for _, d := range []string{classDir, javaDir, mainDir} {
|
||||
if err := os.MkdirAll(d, 0700); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
javacArgs := []string{"-d", filepath.Join(tmpDir, "classes"), "-sourcepath", filepath.Join(tmpDir, "src")}
|
||||
|
||||
fs := token.NewFileSet()
|
||||
for _, p := range typePkgs {
|
||||
goFile := filepath.Join(bindDir, "go_"+p.Name()+"main.go")
|
||||
f, err := os.OpenFile(goFile, os.O_CREATE|os.O_RDWR, 0600)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open: %s: %v", goFile, err)
|
||||
}
|
||||
conf := &bind.GeneratorConfig{Writer: f, Fset: fs, Pkg: p, AllPkg: typePkgs}
|
||||
if err := bind.GenGo(conf); err != nil {
|
||||
return fmt.Errorf("failed to bind %s:%v", p.Name(), err)
|
||||
}
|
||||
if err := f.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
javaFile := strings.Title(p.Name()) + ".java"
|
||||
if err := bindJava(javaDir, javaFile, conf, int(bind.Java)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := bindJava(bindDir, "java_"+p.Name()+".c", conf, int(bind.JavaC)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := bindJava(bindDir, p.Name()+".h", conf, int(bind.JavaH)); err != nil {
|
||||
return err
|
||||
}
|
||||
javacArgs = append(javacArgs, filepath.Join(javaDir, javaFile))
|
||||
}
|
||||
|
||||
bindPkg, err := build.Import(reflect.TypeOf(bind.ErrorList{}).PkgPath(), "", build.FindOnly)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bindJavaPkgDir := filepath.Join(bindPkg.Dir, "java")
|
||||
toCopy := []filePair{
|
||||
{filepath.Join(bindDir, "seq.go"), filepath.Join(bindPkg.Dir, "seq.go.support")},
|
||||
{filepath.Join(bindDir, "seq_java.go"), filepath.Join(bindJavaPkgDir, "seq_android.go.support")},
|
||||
{filepath.Join(bindDir, "seq.c"), filepath.Join(bindJavaPkgDir, "seq_android.c.support")},
|
||||
{filepath.Join(bindDir, "seq.h"), filepath.Join(bindJavaPkgDir, "seq.h")},
|
||||
{filepath.Join(javaDir, "Seq.java"), filepath.Join(bindJavaPkgDir, "Seq.java")},
|
||||
{filepath.Join(javaDir, "LoadJNI.java"), filepath.Join(bindPkg.Dir, "..", "..", "gojava", "LoadJNI.java")},
|
||||
}
|
||||
if err := copyFiles(toCopy); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ioutil.WriteFile(mainFile, []byte(fmt.Sprintf(javaMain, bindPkg.ImportPath)), 0600); err != nil {
|
||||
return err
|
||||
}
|
||||
inc1, inc2 := filepath.Join(javaHome, "include"), filepath.Join(javaHome, "include", runtime.GOOS)
|
||||
flagFile := filepath.Join(bindDir, "gojavacimport.go")
|
||||
if err := ioutil.WriteFile(flagFile, []byte(fmt.Sprintf(javaInclude, inc1, inc2)), 0600); err != nil {
|
||||
return err
|
||||
}
|
||||
dylib := filepath.Join(classDir, "libgojava")
|
||||
back, err := cdTo(mainDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer back()
|
||||
if err := runCommand("go", "build", "-o", dylib, "-buildmode=c-shared", "."); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.Chdir(javaDir); err != nil {
|
||||
return err
|
||||
}
|
||||
javacArgs = append(javacArgs, filepath.Join(javaDir, "Seq.java"), filepath.Join(javaDir, "LoadJNI.java"))
|
||||
if err := runCommand("javac", javacArgs...); err != nil {
|
||||
return err
|
||||
}
|
||||
t, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
w := zip.NewWriter(t)
|
||||
jarDir := filepath.Join(tmpDir, "classes")
|
||||
if err := filepath.Walk(jarDir, func(path string, info os.FileInfo, walkErr error) error {
|
||||
if walkErr != nil {
|
||||
return walkErr
|
||||
}
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
fileName, err := filepath.Rel(jarDir, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f, err := w.Create(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := f.Write(d); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := t.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func cdTo(target string) (func(), error) {
|
||||
cur, err := os.Getwd()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := os.Chdir(target); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return func() {
|
||||
if err := os.Chdir(cur); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
func copyFile(dst, src string) error {
|
||||
d, err := ioutil.ReadFile(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ioutil.WriteFile(dst, d, 0600)
|
||||
}
|
||||
|
||||
type filePair struct {
|
||||
dst string
|
||||
src string
|
||||
}
|
||||
|
||||
func copyFiles(files []filePair) error {
|
||||
for _, p := range files {
|
||||
if err := copyFile(p.dst, p.src); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func bindJava(dir, file string, conf *bind.GeneratorConfig, ft int) error {
|
||||
path := filepath.Join(dir, file)
|
||||
w, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0600)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to generate %s: %v", path, err)
|
||||
}
|
||||
conf.Writer = w
|
||||
defer func() { conf.Writer = nil }()
|
||||
|
||||
switch ft {
|
||||
case int(bind.Java):
|
||||
err = bind.GenJava(conf, "", bind.Java)
|
||||
case int(bind.JavaH):
|
||||
err = bind.GenJava(conf, "", bind.JavaH)
|
||||
case int(bind.JavaC):
|
||||
err = bind.GenJava(conf, "", bind.JavaC)
|
||||
default:
|
||||
err = fmt.Errorf("unsupported bind type: %d", ft)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return w.Close()
|
||||
}
|
||||
|
||||
const javaInclude = `package gojava_bind
|
||||
|
||||
// #cgo CFLAGS: -Wall -I%s -I%s
|
||||
import "C"
|
||||
|
||||
`
|
||||
const javaMain = `package main
|
||||
|
||||
import (
|
||||
_ %q
|
||||
_ ".."
|
||||
)
|
||||
|
||||
func main() {}
|
||||
`
|
42
gojava_test.go
Normal file
42
gojava_test.go
Normal file
@ -0,0 +1,42 @@
|
||||
package gojava
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"os/exec"
|
||||
"os"
|
||||
)
|
||||
|
||||
func TestJavaBind(t *testing.T) {
|
||||
tmpDir, err := ioutil.TempDir("", "gojavatest")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
jar := filepath.Join("/tmp", "gojavatest.jar")
|
||||
if err := createJar(jar,
|
||||
"github.com/sridharv/gomobile-java/bind/testpkg",
|
||||
"github.com/sridharv/gomobile-java/bind/testpkg/secondpkg",
|
||||
"github.com/sridharv/gomobile-java/bind/testpkg/simplepkg",
|
||||
); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
toCopy := []filePair{
|
||||
{filepath.Join(tmpDir, "MoreAsserts.java"), "MoreAsserts.java"},
|
||||
{filepath.Join(tmpDir, "SeqTest.java"), "../gomobile-java/bind/java/SeqTest.java"},
|
||||
}
|
||||
if err := copyFiles(toCopy); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := runCommand("javac", "-cp", jar, "-d", tmpDir, toCopy[0].dst, toCopy[1].dst); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cmd := exec.Command("java", "-cp", jar + ":" + tmpDir, "go.MoreAsserts")
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Stdout = os.Stdout
|
||||
if err := cmd.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user