Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate Java bindings #160

Closed
traversaro opened this issue May 17, 2016 · 5 comments
Closed

Generate Java bindings #160

traversaro opened this issue May 17, 2016 · 5 comments

Comments

@traversaro
Copy link
Member

No description provided.

@traversaro
Copy link
Member Author

traversaro commented May 17, 2016

With some minor annoyance (the automatic generation of setters/getters for each public attribute caused some conflict) I got a preliminary version of the bindings correctly compiling in the feature/java branch : https://github.com/robotology/idyntree/compare/feature/java .

Next steps involve:

@traversaro
Copy link
Member Author

cc @francesco-romano @fiorisi

@traversaro
Copy link
Member Author

cc @francesco-romano

@traversaro
Copy link
Member Author

Closing, as discussed in #392 (comment) .
For future reference, the patch was:

From 454890b22cc28342e755447ef5a5fcd10dedc66b Mon Sep 17 00:00:00 2001
From: Silvio Traversaro <silvio.traversaro@iit.it>
Date: Tue, 17 May 2016 23:24:11 +0200
Subject: [PATCH 1/3] [java] Rename u public attribute in
 ArticulatedBodyInertia buffers

In preparation of the Java bindings generation, rename u in uu.
This is necessary because every public attribute is going to be wrapped
 in Java with a couple of automatically generated set and get, and
the presence in the same class of U and u was generatign two identically
getU() methods.

This change brecks the compilation of Matlab bindings, that will need to
be regenerated and commited before merging the feature/java branch in master.
---
 src/model/include/iDynTree/Model/Dynamics.h    |  2 +-
 src/model/src/Dynamics.cpp                     | 10 +++++-----
 src/model/src/DynamicsLinearization.cpp        | 18 +++++++++---------
 .../DynamicsLinearizationIntegrationTest.cpp   | 10 +++++-----
 4 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/src/model/include/iDynTree/Model/Dynamics.h b/src/model/include/iDynTree/Model/Dynamics.h
index c7e2907c..135e5875 100644
--- a/src/model/include/iDynTree/Model/Dynamics.h
+++ b/src/model/include/iDynTree/Model/Dynamics.h
@@ -113,7 +113,7 @@ namespace iDynTree
         DOFSpatialMotionArray S;
         DOFSpatialForceArray U;
         JointDOFsDoubleArray D;
-        JointDOFsDoubleArray u;
+        JointDOFsDoubleArray uu;
         LinkVelArray linksVel;
         LinkAccArray linksBiasAcceleration;
         LinkAccArray linksAccelerations;
diff --git a/src/model/src/Dynamics.cpp b/src/model/src/Dynamics.cpp
index e237d044..460bc209 100644
--- a/src/model/src/Dynamics.cpp
+++ b/src/model/src/Dynamics.cpp
@@ -281,7 +281,7 @@ void ArticulatedBodyAlgorithmInternalBuffers::resize(const Model& model)
     S.resize(model);
     U.resize(model);
     D.resize(model);
-    u.resize(model);
+    uu.resize(model);
     linksVel.resize(model);
     linksBiasAcceleration.resize(model);
     linksAccelerations.resize(model);
@@ -298,7 +298,7 @@ bool ArticulatedBodyAlgorithmInternalBuffers::isConsistent(const Model& model)
     ok = ok && S.isConsistent(model);
     ok = ok && U.isConsistent(model);
     ok = ok && D.isConsistent(model);
-    ok = ok && u.isConsistent(model);
+    ok = ok && uu.isConsistent(model);
     ok = ok && linksVel.isConsistent(model);
     ok = ok && linksBiasAcceleration.isConsistent(model);
     ok = ok && linkABIs.isConsistent(model);
@@ -398,13 +398,13 @@ bool ArticulatedBodyAlgorithm(const Model& model,
                 size_t dofIndex = toParentJoint->getDOFsOffset();
                 bufs.U(dofIndex) = bufs.linkABIs(visitedLinkIndex)*bufs.S(dofIndex);
                 bufs.D(dofIndex) = bufs.S(dofIndex).dot(bufs.U(dofIndex));
-                bufs.u(dofIndex) = jointTorques(dofIndex) - bufs.S(dofIndex).dot(bufs.linksBiasWrench(visitedLinkIndex));
+                bufs.uu(dofIndex) = jointTorques(dofIndex) - bufs.S(dofIndex).dot(bufs.linksBiasWrench(visitedLinkIndex));
 
                 Ia = bufs.linkABIs(visitedLinkIndex) - ArticulatedBodyInertia::ABADyadHelper(bufs.U(dofIndex),bufs.D(dofIndex));
 
                 pa                 =   bufs.linksBiasWrench(visitedLinkIndex)
                                      + Ia*bufs.linksBiasAcceleration(visitedLinkIndex)
-                                     + bufs.U(dofIndex)*(bufs.u(dofIndex)/bufs.D(dofIndex));
+                                     + bufs.U(dofIndex)*(bufs.uu(dofIndex)/bufs.D(dofIndex));
 
             }
 
@@ -457,7 +457,7 @@ bool ArticulatedBodyAlgorithm(const Model& model,
                bufs.linksAccelerations(visitedLinkIndex) =
                    toParentJoint->getTransform(robotPos.jointPos(),visitedLinkIndex,parentLinkIndex)*bufs.linksAccelerations(parentLinkIndex)
                    + bufs.linksBiasAcceleration(visitedLinkIndex);
-               robotAcc.jointAcc()(dofIndex) = (bufs.u(dofIndex)-bufs.U(dofIndex).dot(bufs.linksAccelerations(visitedLinkIndex)))/bufs.D(dofIndex);
+               robotAcc.jointAcc()(dofIndex) = (bufs.uu(dofIndex)-bufs.U(dofIndex).dot(bufs.linksAccelerations(visitedLinkIndex)))/bufs.D(dofIndex);
                bufs.linksAccelerations(visitedLinkIndex) = bufs.linksAccelerations(visitedLinkIndex) + bufs.S(dofIndex)*robotAcc.jointAcc()(dofIndex);
            }
            else
diff --git a/src/model/src/DynamicsLinearization.cpp b/src/model/src/DynamicsLinearization.cpp
index b8ccff7d..1064f653 100644
--- a/src/model/src/DynamicsLinearization.cpp
+++ b/src/model/src/DynamicsLinearization.cpp
@@ -196,7 +196,7 @@ void ForwardDynamicsLinearizationWrtJointPos(const Model& model,
                 size_t dofIndex = toParentJoint->getDOFsOffset();
                 bufs.dPos[dofDeriv].U(dofIndex) = bufs.dPos[dofDeriv].linkABIs(visitedLinkIndex)*bufs.aba.S(dofIndex);
                 bufs.dPos[dofDeriv].D(dofIndex) = bufs.aba.S(dofIndex).dot(bufs.dPos[dofDeriv].U(dofIndex));
-                bufs.dPos[dofDeriv].u(dofIndex) =  - bufs.aba.S(dofIndex).dot(bufs.dPos[dofDeriv].linksBiasWrench(visitedLinkIndex));
+                bufs.dPos[dofDeriv].uu(dofIndex) =  - bufs.aba.S(dofIndex).dot(bufs.dPos[dofDeriv].linksBiasWrench(visitedLinkIndex));
 
                 double invD = 1/(bufs.aba.D(dofIndex));
                 double d_invD = - invD * bufs.dPos[dofDeriv].D(dofIndex) * invD;
@@ -209,8 +209,8 @@ void ForwardDynamicsLinearizationWrtJointPos(const Model& model,
                 dPos_pa    =  bufs.dPos[dofDeriv].linksBiasWrench(visitedLinkIndex)
                                      + dPos_Ia*bufs.aba.linksBiasAcceleration(visitedLinkIndex)
                                      + Ia*bufs.dPos[dofDeriv].linksBiasAcceleration(visitedLinkIndex)
-                                     + bufs.dPos[dofDeriv].U(dofIndex)*(bufs.aba.u(dofIndex)*invD)
-                                     + bufs.aba.U(dofIndex)*(bufs.dPos[dofDeriv].u(dofIndex)*invD + bufs.aba.u(dofIndex)*d_invD);
+                                     + bufs.dPos[dofDeriv].U(dofIndex)*(bufs.aba.uu(dofIndex)*invD)
+                                     + bufs.aba.U(dofIndex)*(bufs.dPos[dofDeriv].uu(dofIndex)*invD + bufs.aba.uu(dofIndex)*d_invD);
 
             }
 
@@ -246,7 +246,7 @@ void ForwardDynamicsLinearizationWrtJointPos(const Model& model,
 
                 SpatialForceVector pa =   bufs.aba.linksBiasWrench(visitedLinkIndex)
                                      + Ia*bufs.aba.linksBiasAcceleration(visitedLinkIndex)
-                                     + bufs.aba.U(dofIndex)*(bufs.aba.u(dofIndex)/bufs.aba.D(dofIndex));
+                                     + bufs.aba.U(dofIndex)*(bufs.aba.uu(dofIndex)/bufs.aba.D(dofIndex));
 
                 bufs.dPos[dofDeriv].linksBiasWrench(parentLinkIndex) = bufs.dPos[dofDeriv].linksBiasWrench(parentLinkIndex)
                                                                       + parent_dX_visited.transform(parent_X_visited,pa);
@@ -309,8 +309,8 @@ void ForwardDynamicsLinearizationWrtJointPos(const Model& model,
                double invD = 1/(bufs.aba.D(dofIndex));
                double d_invD = - invD * bufs.dPos[dofDeriv].D(dofIndex) * invD;
                double dPos_ddq =
-                    (bufs.aba.u(dofIndex)-bufs.aba.U(dofIndex).dot(bufs.aba.linksAccelerations(visitedLinkIndex)))*d_invD;
-                    (bufs.dPos[dofDeriv].u(dofIndex)
+                    (bufs.aba.uu(dofIndex)-bufs.aba.U(dofIndex).dot(bufs.aba.linksAccelerations(visitedLinkIndex)))*d_invD;
+                    (bufs.dPos[dofDeriv].uu(dofIndex)
                         -bufs.dPos[dofDeriv].U(dofIndex).dot(bufs.aba.linksAccelerations(visitedLinkIndex))
                         -bufs.aba.U(dofIndex).dot(bufs.dPos[dofDeriv].linksAccelerations(visitedLinkIndex)))*invD;
 
@@ -599,13 +599,13 @@ void ForwardDynamicsLinearizationWrtJointVel(const Model& model,
             {
                 assert(toParentJoint->getNrOfDOFs()==1);
                 size_t dofIndex = toParentJoint->getDOFsOffset();
-                bufs.dVel[dofDeriv].u(dofIndex) = -bufs.aba.S(dofIndex).dot(bufs.dVel[dofDeriv].linksBiasWrench(visitedLinkIndex));
+                bufs.dVel[dofDeriv].uu(dofIndex) = -bufs.aba.S(dofIndex).dot(bufs.dVel[dofDeriv].linksBiasWrench(visitedLinkIndex));
 
                 Ia = bufs.aba.linkABIs(visitedLinkIndex) - ArticulatedBodyInertia::ABADyadHelper(bufs.aba.U(dofIndex),bufs.aba.D(dofIndex));
 
                 dVel_dofDeriv_pa   =   bufs.dVel[dofDeriv].linksBiasWrench(visitedLinkIndex)
                                      + Ia*bufs.dVel[dofDeriv].linksBiasAcceleration(visitedLinkIndex)
-                                     + bufs.aba.U(dofIndex)*(bufs.dVel[dofDeriv].u(dofIndex)/bufs.aba.D(dofIndex));
+                                     + bufs.aba.U(dofIndex)*(bufs.dVel[dofDeriv].uu(dofIndex)/bufs.aba.D(dofIndex));
 
             }
 
@@ -659,7 +659,7 @@ void ForwardDynamicsLinearizationWrtJointVel(const Model& model,
                    toParentJoint->getTransform(robotPos.jointPos(),visitedLinkIndex,parentLinkIndex)*bufs.dVel[dofDeriv].linksAccelerations(parentLinkIndex)
                    + bufs.dVel[dofDeriv].linksBiasAcceleration(visitedLinkIndex);
 
-               double dVel_dofDeriv_ddq_dofIndex = (bufs.dVel[dofDeriv].u(dofIndex)-bufs.aba.U(dofIndex).dot(bufs.dVel[dofDeriv].linksAccelerations(visitedLinkIndex)))/bufs.aba.D(dofIndex);
+               double dVel_dofDeriv_ddq_dofIndex = (bufs.dVel[dofDeriv].uu(dofIndex)-bufs.aba.U(dofIndex).dot(bufs.dVel[dofDeriv].linksAccelerations(visitedLinkIndex)))/bufs.aba.D(dofIndex);
 
                A(6+model.getNrOfDOFs()+6+dofIndex,6+model.getNrOfDOFs()+6+dofDeriv) = dVel_dofDeriv_ddq_dofIndex;
 
diff --git a/src/tests/integration/DynamicsLinearizationIntegrationTest.cpp b/src/tests/integration/DynamicsLinearizationIntegrationTest.cpp
index 021648d0..ab1e67b3 100644
--- a/src/tests/integration/DynamicsLinearizationIntegrationTest.cpp
+++ b/src/tests/integration/DynamicsLinearizationIntegrationTest.cpp
@@ -108,8 +108,8 @@ void checkDifferenceInBuffers(const ForwardDynamicsLinearizationInternalBuffers
             if( verbose )
             {
                  std::cerr << "Check difference in buffers for dof " << dof << std::endl;
-                 std::cerr << "Norm of diff in u : "
-                           << fabs(bufs.dVel[dofDeriv].u(dof)-numBufs.dVel[dofDeriv].u(dof)) << std::endl;
+                 std::cerr << "Norm of diff in uu : "
+                           << fabs(bufs.dVel[dofDeriv].uu(dof)-numBufs.dVel[dofDeriv].uu(dof)) << std::endl;
             }
         }
     }
@@ -145,7 +145,7 @@ void checkDifferenceInBuffers(const ForwardDynamicsLinearizationInternalBuffers
             {
                  std::cerr << "Check difference in buffers for dof " << dof << std::endl;
                  std::cerr << "Norm of diff in u : "
-                           << fabs(bufs.dPos[dofDeriv].u(dof)-numBufs.dPos[dofDeriv].u(dof)) << std::endl;
+                           << fabs(bufs.dPos[dofDeriv].uu(dof)-numBufs.dPos[dofDeriv].uu(dof)) << std::endl;
                  std::cerr << "Norm of diff in D : "
                            << fabs(bufs.dPos[dofDeriv].D(dof)-numBufs.dPos[dofDeriv].D(dof)) << std::endl;
                  std::cerr << " D "
@@ -218,9 +218,9 @@ void fillLinBufsWithNumericalDerivativesWrtJointQuantity(const ArticulatedBodyAl
     }
 
     // set dofs buffers
-    for(size_t dof=0; dof < numBufs.u.size(); dof++ )
+    for(size_t dof=0; dof < numBufs.uu.size(); dof++ )
     {
-        numBufs.u(dof) = (bufsUpper.u(dof) - bufsLower.u(dof))/step;
+        numBufs.uu(dof) = (bufsUpper.uu(dof) - bufsLower.uu(dof))/step;
     }
 }
 

From 09a88e65a0b95e50558a6b190cc555d5ec3b9ec7 Mon Sep 17 00:00:00 2001
From: Silvio Traversaro <silvio.traversaro@iit.it>
Date: Tue, 17 May 2016 23:29:22 +0200
Subject: [PATCH 2/3] [java] Add preliminary java bindings support

The support can be enabled with the IDYNTREE_USES_JAVA cmake option.
Currently the cmake produce a jar with all the generated class files.
---
 bindings/CMakeLists.txt      |  9 ++++++++-
 bindings/iDynTree.i          |  5 +++++
 bindings/java/CMakeLists.txt | 34 ++++++++++++++++++++++++++++++++++
 bindings/java/java.i         |  3 +++
 4 files changed, 50 insertions(+), 1 deletion(-)
 create mode 100644 bindings/java/CMakeLists.txt
 create mode 100644 bindings/java/java.i

diff --git a/bindings/CMakeLists.txt b/bindings/CMakeLists.txt
index 151131bd..72e612a8 100644
--- a/bindings/CMakeLists.txt
+++ b/bindings/CMakeLists.txt
@@ -9,6 +9,7 @@ option(IDYNTREE_USES_LUA "Do you want to create the Lua bindings" FALSE)
 option(IDYNTREE_USES_MATLAB "Do you want to create the MATLAB bindings" FALSE)
 option(IDYNTREE_USES_OCTAVE "Do you want to create the OCTAVE bindings" FALSE)
 option(IDYNTREE_GENERATE_MATLAB "Enable if you have the experimental version of SWIG necessary for generating the Matlab wrapper" FALSE)
+option(IDYNTREE_USES_JAVA "Do you want to create the Java Interface" FALSE)
 
 find_package(SWIG)
 # It is possible to compile matlab/octave bindings without using SWIG
@@ -43,15 +44,21 @@ if(SWIG_FOUND OR IDYNTREE_USES_MATLAB OR IDYNTREE_USES_OCTAVE)
     if(IDYNTREE_USES_PYTHON)
         add_subdirectory(python)
     endif(IDYNTREE_USES_PYTHON)
+    
+    if(IDYNTREE_USES_JAVA)
+       add_subdirectory(java)
+    endif()
 
     if(IDYNTREE_USES_MATLAB OR IDYNTREE_GENERATE_MATLAB OR IDYNTREE_USES_OCTAVE)
         add_subdirectory(matlab)
     endif()
 endif()
 
+
 if(IDYNTREE_USES_PYTHON OR
    IDYNTREE_USES_LUA    OR
-   IDYNTREE_GENERATED_MATLAB)
+   IDYNTREE_GENERATED_MATLAB OR
+   IDYNTREE_USES_JAVA)
    if(NOT SWIG_FOUND)
        MESSAGE(FATAL_ERROR "Swig not found, impossible to compile or generate iDynTree bindings.")
    endif()
diff --git a/bindings/iDynTree.i b/bindings/iDynTree.i
index eb406fb8..b831a869 100644
--- a/bindings/iDynTree.i
+++ b/bindings/iDynTree.i
@@ -19,6 +19,11 @@
 %include "./python/python.i"
 #endif
 
+// Java
+#ifdef SWIGJAVA
+%include "./java/java.i"
+#endif
+
 // Matlab
 #ifdef SWIGMATLAB
 %include "./matlab/matlab.i"
diff --git a/bindings/java/CMakeLists.txt b/bindings/java/CMakeLists.txt
new file mode 100644
index 00000000..08f0baa0
--- /dev/null
+++ b/bindings/java/CMakeLists.txt
@@ -0,0 +1,34 @@
+set(CMAKE_SWIG_FLAGS "-Wextra;-module;iDynTree;-package;iDynTree")
+
+find_package(Java REQUIRED COMPONENTS Runtime Development)
+find_package(JNI  REQUIRED)
+
+include(UseJava)
+
+# CMake structure inspired by http://stackoverflow.com/a/31750207/1379427
+
+# Specify where to place generated *.java files
+SET(CMAKE_SWIG_OUTDIR "${CMAKE_CURRENT_BINARY_DIR}/java")
+
+# Add module
+set(target_name iDynTree_java)
+set_source_files_properties(../iDynTree.i PROPERTIES CPLUSPLUS ON)
+swig_add_module(${target_name} java ../iDynTree.i)
+include_directories(SYSTEM ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH2})
+
+# Create directory for the *class files
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/classes")
+
+# Create JAR including compiled .class file 
+add_custom_command(TARGET ${target_name} POST_BUILD
+                   COMMAND "${Java_JAVAC_EXECUTABLE}" -d classes java/*.java
+                   COMMAND "${Java_JAR_EXECUTABLE}" -cfM iDynTree.jar -C classes .)
+
+# Store Path to iDynTree JAR in variable:
+SET(IDYNTREE_JAR "${CMAKE_CURRENT_BINARY_DIR}/iDynTree.jar")
+
+
+# if compile tests execute also java tests
+# if(IDYNTREE_COMPILE_TESTS)
+#    add_subdirectory(tests)
+# endif()
diff --git a/bindings/java/java.i b/bindings/java/java.i
new file mode 100644
index 00000000..2eaad1ea
--- /dev/null
+++ b/bindings/java/java.i
@@ -0,0 +1,3 @@
+// getSemantics / setSemantics are already generated in the GeomVector3 because
+// in Java SWIG get/set methods are generated for each public attribute
+%ignore *::setSemantics;

From fc2cd0adbd8f0878e3e9ee2daa4fae75ed7bcaad Mon Sep 17 00:00:00 2001
From: Francesco Romano <francesco.romano.1987@gmail.com>
Date: Thu, 16 Nov 2017 18:17:24 +0100
Subject: [PATCH 3/3] Updated JAVA bindings cmake

Supported generation and installation of .JAR files
---
 bindings/java/CMakeLists.txt | 138 +++++++++++++++++++++++++++++------
 1 file changed, 115 insertions(+), 23 deletions(-)

diff --git a/bindings/java/CMakeLists.txt b/bindings/java/CMakeLists.txt
index 08f0baa0..7ede35bf 100644
--- a/bindings/java/CMakeLists.txt
+++ b/bindings/java/CMakeLists.txt
@@ -1,34 +1,126 @@
-set(CMAKE_SWIG_FLAGS "-Wextra;-module;iDynTree;-package;iDynTree")
-
-find_package(Java REQUIRED COMPONENTS Runtime Development)
-find_package(JNI  REQUIRED)
+# Copyright: (C) 2017 iCub Facility
+# Authors: Francesco Romano, Daniele Domenichelli
+# CopyPolicy: Released under the terms of the LGPLv2.1 or later, see LGPL.TXT
 
+# include CMake Java utilities and JNI
+find_package(Java REQUIRED)
+find_package(JNI REQUIRED)
 include(UseJava)
+include(${SWIG_USE_FILE})
+
+# this is set in the parent directory, but for some reason it does not get inherited
+set_source_files_properties(../iDynTree.i PROPERTIES CPLUSPLUS ON)
 
-# CMake structure inspired by http://stackoverflow.com/a/31750207/1379427
+if(NOT ${Java_VERSION_MAJOR} VERSION_LESS 9)
+  # Java >= 9
+  set(JAVA_RELEASE_VERSION 7 CACHE STRING "Compile for a specific VM version. See javac --help (--release option)")
+  mark_as_advanced(JAVA_RELEASE_VERSION)
+  if(NOT JAVA_RELEASE_VERSION STREQUAL "")
+    list(APPEND CMAKE_JAVA_COMPILE_FLAGS "--release" "${JAVA_RELEASE_VERSION}")
+  endif()
+  # clean old variable
+  unset(JAVA_TARGET_VERSION CACHE)
+  unset(JAVA_SOURCE_VERSION CACHE)
+else()
+  # Java < 9: --release option not present
+  set(JAVA_TARGET_VERSION ${Java_VERSION_MINOR} CACHE STRING "Java target version. See javac --help (-target option)")
+  set(JAVA_SOURCE_VERSION ${Java_VERSION_MINOR} CACHE STRING "Java source version. See javac --help (-source option)")
+  mark_as_advanced(JAVA_TARGET_VERSION)
+  mark_as_advanced(JAVA_SOURCE_VERSION)
+  if(NOT JAVA_TARGET_VERSION STREQUAL "")
+    list(APPEND CMAKE_JAVA_COMPILE_FLAGS "-target" "${JAVA_TARGET_VERSION}")
+  endif()
+  if(NOT JAVA_SOURCE_VERSION STREQUAL "")
+    list(APPEND CMAKE_JAVA_COMPILE_FLAGS "-source" "${JAVA_SOURCE_VERSION}")
+  endif()
+  unset(JAVA_RELEASE_VERSION CACHE)
+endif()
 
-# Specify where to place generated *.java files
-SET(CMAKE_SWIG_OUTDIR "${CMAKE_CURRENT_BINARY_DIR}/java")
+set(JAVA_FLAGS "" CACHE STRING "Additional flags to be passed to javac. E.g. -bootclasspath if you want to cross compile")
+mark_as_advanced(JAVA_FLAGS)
+list(APPEND CMAKE_JAVA_COMPILE_FLAGS "${JAVA_FLAGS}")
 
-# Add module
-set(target_name iDynTree_java)
-set_source_files_properties(../iDynTree.i PROPERTIES CPLUSPLUS ON)
-swig_add_module(${target_name} java ../iDynTree.i)
+# SWIG JAVA file generation
+set(CMAKE_SWIG_OUTDIR "${CMAKE_CURRENT_BINARY_DIR}")
+set(CMAKE_SWIG_FLAGS "-package;iDynTree;-Wall;-module;iDynTree;${SWIG_COMMON_FLAGS}")
+
+# this includes are needed to compile the JNI lib
 include_directories(SYSTEM ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH2})
 
-# Create directory for the *class files
-file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/classes")
+swig_add_library(iDynTree_java
+                 LANGUAGE java
+                 SOURCES ../iDynTree.i)
+
+swig_link_libraries(iDynTree_java ${IDYNTREE_LIBRARIES}) #SWIG_YARP_LIBRARIES
+
+if(NOT MSVC)
+  check_cxx_compiler_flag("-Wno-strict-aliasing" CXX_HAS_WNO_STRICT_ALIASING)
+  if(CXX_HAS_WNO_STRICT_ALIASING)
+    target_compile_options(${SWIG_MODULE_iDynTree_java_REAL_NAME} PRIVATE "-Wno-strict-aliasing")
+  endif()
+endif()
+
+# issue on MINGW where C++ name-mangling prevents java finding methods
+if(MINGW)
+  message(STATUS "untested MINGW patch - see CMakeLists.txt")
+  set_target_properties(${SWIG_MODULE_iDynTree_java_REAL_NAME} PROPERTIES
+    LINK_FLAGS "--add-stdcall-alias")
+endif(MINGW)
+
+set(_CMAKE_INSTALL_JNIDIR "${CMAKE_INSTALL_LIBDIR}/jni")
+set(CMAKE_INSTALL_JNIDIR ${_CMAKE_INSTALL_JNIDIR} CACHE PATH "java bindings (${_CMAKE_INSTALL_JNIDIR})")
+mark_as_advanced(CMAKE_INSTALL_JNIDIR)
+if(NOT IS_ABSOLUTE ${CMAKE_INSTALL_JNIDIR})
+  set(CMAKE_INSTALL_FULL_JNIDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_JNIDIR}")
+else()
+  set(CMAKE_INSTALL_FULL_JNIDIR "${CMAKE_INSTALL_JNIDIR}")
+endif()
+
+set_target_properties(${SWIG_MODULE_iDynTree_java_REAL_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_JNIDIR})
+
+# Update RPATH
+if(NOT CMAKE_SKIP_RPATH AND NOT CMAKE_SKIP_INSTALL_RPATH)
+  file(RELATIVE_PATH _rel_path "${CMAKE_INSTALL_FULL_JNIDIR}" "${CMAKE_INSTALL_FULL_LIBDIR}")
+  get_target_property(_current_rpath "${SWIG_MODULE_iDynTree_java_REAL_NAME}" INSTALL_RPATH)
+  if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+    list(APPEND _current_rpath "@loader_path/${_rel_path}")
+  else()
+    list(APPEND _current_rpath "\$ORIGIN/${_rel_path}")
+  endif()
+  set_target_properties(${SWIG_MODULE_iDynTree_java_REAL_NAME} PROPERTIES INSTALL_RPATH "${_current_rpath}")
+endif()
+
+
+set(CMAKE_JNI_TARGET TRUE)
+set(CMAKE_JAVA_TARGET_OUTPUT_DIR "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/iDynTree/java")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/GenerateSwigiDynTreeFileList.cmake"
+"file(GLOB _JAVA_COMPILE_FILES \"${CMAKE_SWIG_OUTDIR}/*.java\")
+string(REPLACE \";\" \"\\\"\\n\\\"\" _JAVA_COMPILE_STRING \"\\\"\${_JAVA_COMPILE_FILES}\\\"\")
+file(MAKE_DIRECTORY \"${CMAKE_JAVA_TARGET_OUTPUT_DIR}\")
+file(WRITE \"${CMAKE_JAVA_TARGET_OUTPUT_DIR}${CMAKE_FILES_DIRECTORY}/idyntree_java_jar.dir/swig_java_filelist\" \${_JAVA_COMPILE_STRING})
+")
+
+add_custom_command(TARGET ${SWIG_MODULE_iDynTree_java_REAL_NAME} POST_BUILD
+                   COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/GenerateSwigiDynTreeFileList.cmake"
+                   COMMENT "Generating list of JAVA files generated by swig")
+
 
-# Create JAR including compiled .class file 
-add_custom_command(TARGET ${target_name} POST_BUILD
-                   COMMAND "${Java_JAVAC_EXECUTABLE}" -d classes java/*.java
-                   COMMAND "${Java_JAR_EXECUTABLE}" -cfM iDynTree.jar -C classes .)
+add_jar(idyntree_java_jar
+        SOURCES @${CMAKE_JAVA_TARGET_OUTPUT_DIR}${CMAKE_FILES_DIRECTORY}/idyntree_java_jar.dir/swig_java_filelist
+        OUTPUT_NAME iDynTree
+        VERSION ${iDynTree_VERSION})
 
-# Store Path to iDynTree JAR in variable:
-SET(IDYNTREE_JAR "${CMAKE_CURRENT_BINARY_DIR}/iDynTree.jar")
+add_dependencies(idyntree_java_jar ${SWIG_MODULE_iDynTree_java_REAL_NAME})
 
+# installation part
+install(TARGETS ${SWIG_MODULE_iDynTree_java_REAL_NAME}
+        DESTINATION ${CMAKE_INSTALL_JNIDIR}
+        COMPONENT bindings_java)
 
-# if compile tests execute also java tests
-# if(IDYNTREE_COMPILE_TESTS)
-#    add_subdirectory(tests)
-# endif()
+install_jar(idyntree_java_jar
+            DESTINATION ${CMAKE_INSTALL_DATADIR}/iDynTree/java
+            COMPONENT bindings_java)
+install_jni_symlink(idyntree_java_jar
+                    DESTINATION ${CMAKE_INSTALL_DATADIR}/java
+                    COMPONENT bindings_java)

@traversaro
Copy link
Member Author

@Nicogene @mfussi66 @pattacini this issue (and the connected PR #392) are the original attemp to create Java bindings as part of the creo2urdf project. If necessary it should be relatively easy to revive it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant