Git Product home page Git Product logo

j2c's Introduction

Introduction

J2C will convert Java code into hopefully compilable C++(11) code. It works on source level, translating Java source code constructs into their rough equivalents in C++ . The output will be reasonably valid C++ code that looks a lot like its Java counterpart and hopefully works mostly the same.

The translation is based on The Java Language Specification, Third Edition, by Gosling, James and Joy, Bill and Steele, Guy and Bracha, Gilad (that's Java 1.6). The translated code should be valid as specified by the ISO/IEC 14882:2011 C++ standard (or C++11 as the rest of the world knows it).

Status

This project is an idea I've been wanting to try out written down in code. Think of it as a paper napkin with some notes on, but in this case, the notes compile and sometimes spit out working stuff. In other words, no guarantees and no quality control label.

That said, j2c successfully converts most of OpenJDK 6 and SWT 3.7 to C++ that compiles and passes a quick ocular inspection. Most language features of Java 1.6 are covered (i e you'll still need a JDK and runtime).

With a few patches and implementations of native methods in the converted OpenJDK code, the included Hello test prints it's message. A more complete example would need a more complete runtime, either by implementing the native and JVM parts of a class library or by implementing the stubs that are generated for missing dependencies.

This is the first time I write an Eclipse plugin, so be nice.

Install / Run

J2C comes in the form of an Eclipse plugin. You need at least Eclipse 3.8+ and Java 1.6+ to run this plugin!

The most recent version of the project is available as source code. You can get it either from Eclipse labs (https://code.google.com/a/eclipselabs.org/p/j2c/) (main site) or github (https://github.com/arnetheduck/j2c) (backup).

From time to time, a release may appear at the Eclipse labs site - see https://code.google.com/a/eclipselabs.org/p/j2c/downloads/list . About that same time, the update site (http://j2c.eclipselabs.org.codespot.com/hg.site/) should be updated.

If you installed via site, it should just work.

If you downloaded the jar, copy it to $ECLIPSE_HOME/dropins.

If you downloaded the source code you'll have run the plugin by opening the project in Eclipse and starting a new Eclipse test instance by using the run button in the plugin.xml overview.

Once you have the plugin running, set up your Java code as a Java Project. Eclipse must be able to compile your code for J2C do to its work!

Once the Java Project is set up (with all dependencies etc), you can run J2C by right-clicking the project (or a class/package) in the 'Project Explorer' or 'Package Explorer' view and choosing the 'Translate to C++' option. You will need to create a folder for the conversion output - the plugin will tell you where.

The generated code will contain references to your JRE (stuff from the java.* packages), as well as some generic helpers. The JRE dependencies will likely be stubbed out in the ext folder in the generated code, and trivial, non-working implementations of the rest can be found in j2c.cpp. You'll need to supplant the converted code with implementations of all JRE features you're using, or replace them manually to use equivalents from C++ libraries such as STL.

The code won't work out of the box

Testing

The test project contains a few cases which should be handled correctly by the translator (by correctly, I mean that they compile with g++ 4.7). You'll find a CDT project in ctest that builds using the generated Makefile after running the plugin on the test project.

Output

For each Java class, j2c will output a header file and its implementation. Inner classes end up in separate .h/.cpp pairs. Native method stubs will be put in a separate file for your editing pleasure.

Classes for which there is no source will have a header written as well as a stub file with empty implementations. Throughout, the heap will be used to allocate class instances but no attempt is made to collect garbage - I recommend Boehm's garbage collector for that.

What's missing (that I can think of right now)

  • Reflection
  • Anything involving byte code (class loading, dynamic code generation, etc)

Helping out

Patches and forks are most welcome, as is testing, but please don't report issues unless you also attach a simple test case.

= Final words = Send me a note if you manage (or not) to do something useful with this converter!

Licensing

The project is licensed under the Eclipse Public License 1.0.

Thanks

No animals were hurt while writing this code, but the Nightwatchman might have sore fingers and throat from all that playing...

Have fun, Jacek Sieka (arnetheduck using google mail point com)

j2c's People

Contributors

arnetheduck avatar

Watchers

 avatar  avatar  avatar

j2c's Issues

Unable to run at all - Menu item doesn't appear

What steps will reproduce the problem?
1. install plugin by copying into dropins folder
2. restart Eclipse (tried with 3.7.2 and also more recent Kepler install)
3. right click on project, on package, on file in Java project

I was looking for a "convert to C++" menu item but couldn't find it.

I also tried building the project from source, launching a separate eclipse 
application running the plugin, but still couldn't get the menu to show up.

Is there an eclipse update site for this plugin?  I'm used to installing most 
eclipse plugins that way.

Original issue reported on code.google.com by [email protected] on 10 Aug 2013 at 8:32

  • Merged into: #4

Naming conflict: enum class c'tor always has an argument called "name"

This one is a bit meta.

In the JDK sources we have this:

enum Source {
    private String name;
    private Source(String name) {
        this.name = name;
    }
}

in j2c we have this:

    public static String printEnumCtorParams(Transformer ctx, PrintWriter pw,
            ITypeBinding type, String sep, DepInfo deps) {
        if (type.isEnum()) {
            pw.print(sep + "::java::lang::String* name, int ordinal");
            deps.soft(ctx.resolve(String.class));
            return ", ";
        }

        return sep;
    }


Hence name/ordinal are off limits for member names in java enums. It looks like 
a simple fix.

Original issue reported on code.google.com by [email protected] on 5 Sep 2013 at 6:38

Something about java.nio.ByteOrder.LITTLE_ENDIAN fails to transpile

In Guava there is this line of code:

void 
com::google::common::primitives::UnsignedBytes_LexicographicalComparatorHolder_U
nsafeComparator::clinit() {
...
littleEndian_ = 
npc(::java::nio::ByteOrder::nativeOrder())->equals(::java::nio::ByteOrder::LITTL
E_ENDIAN());
...
}

It makes GCC give this error:

In file included from /usr/include/ctype.h:41:0,
                 from /usr/local/google/home/hearn/gcc-install/include/c++/4.8.1/cctype:42,
                 from /usr/local/google/home/hearn/gcc-install/include/c++/4.8.1/bits/localefwd.h:42,
                 from /usr/local/google/home/hearn/gcc-install/include/c++/4.8.1/ios:41,
                 from /usr/local/google/home/hearn/gcc-install/include/c++/4.8.1/ostream:38,
                 from /usr/local/google/home/hearn/gcc-install/include/c++/4.8.1/iterator:64,
                 from src/SubArray.hpp:3,
                 from src/com/google/common/primitives/UnsignedBytes_LexicographicalComparatorHolder_UnsafeComparator.cpp:26:
src/com/google/common/primitives/UnsignedBytes_LexicographicalComparatorHolder_U
nsafeComparator.cpp: In constructor 
‘com::google::common::primitives::UnsignedBytes_LexicographicalComparatorHolde
r_UnsafeComparator::clinit()::clinit_::clinit_()’:
src/com/google/common/primitives/UnsignedBytes_LexicographicalComparatorHolder_U
nsafeComparator.cpp:178:100: error: expected unqualified-id before numeric 
constant
         littleEndian_ = npc(::java::nio::ByteOrder::nativeOrder())->equals(::java::nio::ByteOrder::LITTLE_ENDIAN());


I'm not sure what about this makes it unhappy but I didn't investigate.

Original issue reported on code.google.com by [email protected] on 5 Sep 2013 at 4:30

Guava: bad casts cause compile failure

Again in Guava MapMaker class we see this code:

  public <K, V> ConcurrentMap<K, V> makeMap() {
    if (!useCustomMap) {
      return new ConcurrentHashMap<K, V>(getInitialCapacity(), 0.75f, getConcurrencyLevel());
    }
    return (nullRemovalCause == null)
        ? new MapMakerInternalMap<K, V>(this)
        : new NullConcurrentMap<K, V>(this);
  }

The last line is converted to:

    return (nullRemovalCause == nullptr) ? static_cast< ::java::util::AbstractMap* >(new MapMakerInternalMap(this)) : static_cast< ::java::util::AbstractMap* >(new MapMaker_NullConcurrentMap(this));

... the static casts here aren't right and result in compile failures:

src/com/google/common/collect/MapMaker.cpp: In member function ‘virtual 
java::util::concurrent::ConcurrentMap* 
com::google::common::collect::MapMaker::makeMap()’:
src/com/google/common/collect/MapMaker.cpp:241:197: error: cannot convert 
‘java::util::AbstractMap*’ to ‘java::util::concurrent::ConcurrentMap*’ 
in return
     return (nullRemovalCause == nullptr) ? static_cast< ::java::util::AbstractMap* >(new MapMakerInternalMap(this)) : static_cast< ::java::util::AbstractMap* >(new MapMaker_NullConcurrentMap(this));

Original issue reported on code.google.com by [email protected] on 5 Sep 2013 at 4:34

Guava: more naming conflict bugs

Guava MapMaker class contains this delightful nugget:

public abstract class GenericMapMaker<K0, V0> {
    // Set by MapMaker, but sits in this class to preserve the type relationship
  @GwtIncompatible("To be supported")
  RemovalListener<K0, V0> removalListener;
}

public final class MapMaker extends GenericMapMaker<Object, Object> {
  @Deprecated
  @GwtIncompatible("To be supported")
  <K, V> GenericMapMaker<K, V> removalListener(RemovalListener<K, V> listener) {
    checkState(this.removalListener == null);

    ....
  }
}

The checkState call is converted to:

::com::google::common::base::Preconditions::checkState(java_cast< 
MapMaker_RemovalListener* >(this->removalListener) == nullptr);

which fails to compile with:

src/com/google/common/collect/MapMaker.cpp: In member function 
‘com::google::common::collect::GenericMapMaker* 
com::google::common::collect::MapMaker::removalListener(com::google::common::col
lect::MapMaker_RemovalListener*)’:
src/com/google/common/collect/MapMaker.cpp:229:120: error: no matching function 
for call to ‘java_cast(<unresolved overloaded function type>)’
     ::com::google::common::base::Preconditions::checkState(java_cast< MapMaker_RemovalListener* >(this->removalListener) == nullptr);
                                                                                                                        ^
src/com/google/common/collect/MapMaker.cpp:229:120: note: candidate is:
src/com/google/common/collect/MapMaker.cpp:32:10: note: template<class T, class 
U> T java_cast(U*)
 static T java_cast(U* u)
          ^
src/com/google/common/collect/MapMaker.cpp:32:10: note:   template argument 
deduction/substitution failed:
src/com/google/common/collect/MapMaker.cpp:229:120: note:   mismatched types 
‘U*’ and ‘com::google::common::collect::GenericMapMaker* 
(com::google::common::collect::MapMaker::*)(com::google::common::collect::MapMak
er_RemovalListener*)’
     ::com::google::common::base::Preconditions::checkState(java_cast< MapMaker_RemovalListener* >(this->removalListener) == nullptr);
                                                                                                                        ^
src/com/google/common/collect/MapMaker.cpp:229:120: note:   could not resolve 
address from overloaded function 
‘((com::google::common::collect::MapMaker*)this)->com::google::common::collect
::MapMaker::removalListener’


I guess the issue is the naming ambiguity between members and methods again.

Original issue reported on code.google.com by [email protected] on 5 Sep 2013 at 4:33

"Convert to C++" does not appear when right-clicking a project.

What steps will reproduce the problem?
1. Put jar into dropins directory
2. Open a Java project in Eclipse 3.7.2
3. Right click the project

What is the expected output? What do you see instead?

The option to convert the project to C++ does not appear in the menu when I 
right click on my projects. I see the regular set of options, but not the 
"Convert to C++" option.

What version of the product are you using? On what operating system?

Eclipse Indigo 3.7.2, latest release, on 64-bit Linux, RHEL6. I also tested it 
with Eclipse Juno.

Please provide any additional information below.

All of my projects are also plug-ins that are used in a large RCP environment. 
Some of them we want to convert to C++.

Original issue reported on code.google.com by [email protected] on 4 Feb 2013 at 10:00

How to run?

How can we run the jar file? I have looked for a description but could not find 
one.
Best Regards


Original issue reported on code.google.com by [email protected] on 25 Apr 2013 at 10:19

ext/src/java/awt/Container.hpp:211:33: error: ‘ContainerListenerArray’ in namespace ‘java::awt::event’ does not name a type virtual ::java::awt::event::ContainerListenerArray* getContainerListeners();

What steps will reproduce the problem?
1. hit translate to c++ button
2. waited for the folder "cwilsim-gc" to stop being written to
3. navigated there and ran make

What is the expected output? What do you see instead?
expected it to build


What version of the product are you using? latest from eclipse repo on j2c main 
page
On what operating system? arch linux


Please provide any additional information below.

sirus cwilsim-gc :( $make
Building with "g++ -Isrc -Iext/src -g -pipe -std=gnu++11"
Compile src/CondVar.cpp
Compile src/Controller.cpp
In file included from ext/src/java/awt/Window.hpp:23:0,
                 from ext/src/java/awt/Frame.hpp:13,
                 from ext/src/javax/swing/JFrame.hpp:11,
                 from src/Wilsim.hpp:8,
                 from src/Controller.cpp:20:
ext/src/java/awt/Container.hpp:211:33: error: ‘ContainerListenerArray’ in 
namespace ‘java::awt::event’ does not name a type
     virtual ::java::awt::event::ContainerListenerArray* getContainerListeners();
                                 ^
Makefile:368: recipe for target 'obj/Controller.o' failed
make: *** [obj/Controller.o] Error 1


please let me know of additional files or anything I can help supply.
the project I'm working on is open source and on github so I can supply a uri 
or whatever needed. 

let me know if I need to supply the output of any commands on my system.

Original issue reported on code.google.com by [email protected] on 3 Nov 2014 at 8:31

FFT

What steps will reproduce the problem?
1.
2.
3.

What is the expected output? What do you see instead?


What version of the product are you using? On what operating system?


Please provide any additional information below.


Original issue reported on code.google.com by [email protected] on 13 Mar 2013 at 1:54

Attachments:

Guava Joiner.MapJoiner fails to compile

This code:

public <A extends Appendable,
        I extends Object & Iterable<? extends Entry<?, ?>> & Iterator<? extends Entry<?, ?>>>
        A appendTo(A appendable, I entries) throws IOException {
      Iterator<? extends Entry<?, ?>> iterator = entries;
      return appendTo(appendable, iterator);
    }

compiles to:

/* <I extends Object & Iterable<? extends Entry<?,?>> & Iterator<? extends 
Entry<?,?>>> */java::lang::String* 
com::google::common::base::Joiner_MapJoiner::join(::java::lang::Object* 
entries) /* throws(IOException) */
{
    ::java::util::Iterator* iterator = entries;
    return join(static_cast< ::java::util::Iterator* >(iterator));
}

which then fails due to the need to cast Object to Iterator:

    ::java::util::Iterator* iterator = java_cast< ::java::util::Iterator* >(entries);

fixes it.

The type signature of that method is pretty crazy - I don't know why it fails 
to translate though.

Original issue reported on code.google.com by [email protected] on 12 Jul 2013 at 1:36

init_jvm()

What is in init_jvm() external method ? In this method I start a native JVM. Or 
what can I do in this method for JVM.

Original issue reported on code.google.com by [email protected] on 12 Mar 2013 at 11:21

Triply nested classes don't resolve ParentClass.this correctly

Guava has a class structure like this in AbstractMultimap:

class X implements Y {}

class A {
  class B extends X {
    class C {
      public Y get() {
        return B.this;
      }
    }
  }
}

It gets mistranslated to something like this:

  return A_B_this->A_this;

when the correct translation is

  return A_B_this;

Original issue reported on code.google.com by [email protected] on 12 Jul 2013 at 1:52

Protobufs: covariant return types mess

This one could be very hard to fix (or maybe impossible?).

Basically the java protobufs library is a pain in the ass and I think would (in 
c++) require forward declaration of inheritance hierarchies to translate 
naturally.

https://code.google.com/p/protobuf/

I'm not quite sure how to reduce this to a minimal test case.

public abstract class AbstractMessage extends AbstractMessageLite
                                      implements Message {
}

public abstract class AbstractMessageLite implements MessageLite {}

public interface Message extends MessageLite, MessageOrBuilder {
}

public interface MessageLite extends MessageLiteOrBuilder {}

public interface MessageOrBuilder extends MessageLiteOrBuilder {
  // (From MessageLite, re-declared here only for return type covariance.)
  //@Override (Java 1.6 override semantics, but we must support 1.5)
  Message getDefaultInstanceForType();
}

public interface MessageLiteOrBuilder {
  MessageLite getDefaultInstanceForType();
}

So here the MessageOrBuilder interface declares a method that returns a 
Message, but Message itself extends MessageOrBuilder.

In file included from src/com/google/protobuf/Message.hpp:9:0,
                 from src/com/google/protobuf/AbstractMessage.hpp:11,
                 from src/com/google/protobuf/AbstractMessage.cpp:2:
src/com/google/protobuf/MessageOrBuilder.hpp:14:23: error: invalid covariant 
return type for ‘virtual com::google::protobuf::MessageOrBuilder* 
com::google::protobuf::MessageOrBuilder::getDefaultInstanceForType()’
     MessageOrBuilder* getDefaultInstanceForType() = 0;
                       ^
In file included from src/com/google/protobuf/MessageLite.hpp:8:0,
                 from src/com/google/protobuf/AbstractMessageLite.hpp:9,
                 from src/com/google/protobuf/AbstractMessage.hpp:10,
                 from src/com/google/protobuf/AbstractMessage.cpp:2:
src/com/google/protobuf/MessageLiteOrBuilder.hpp:12:26: error:   overriding 
‘virtual com::google::protobuf::MessageLite* 
com::google::protobuf::MessageLiteOrBuilder::getDefaultInstanceForType()’
     virtual MessageLite* getDefaultInstanceForType() = 0;


It's a mess and might be easier if you just grab the library yourself to see 
what's going on :(

Original issue reported on code.google.com by [email protected] on 5 Sep 2013 at 4:51

command line tool

j2c looks great, i want to give it a try, but i do not use Eclipse.  Why not 
package this as a normal command line tool?

Original issue reported on code.google.com by [email protected] on 12 Feb 2015 at 9:55

  • Merged into: #1

The tool is can't be successfully installed.

1. I followed the instruction of README.md. First downloaded the jar, copy it 
to $ECLIPSE_HOME/dropins. Second started the eclipse, it seems no work. 

2. I expected 'Translate to C++' option will appear, but it didn't, there is 
nothing when i right-clicking the project (or a class/package) in the 'Project 
Explorer' or
'Package Explorer' view .

3. The version of the product is as follows and my operating system is Windows 
XP. 
/***********************************************************/
se.arnetheduck.j2c_0.2.2.201207071747.jar

Eclipse SDK

Version: 3.8.0
Build id: I20120608-1200

(c) Copyright Eclipse contributors and others 2000, 2012.  All rights reserved.
Visit http://www.eclipse.org/platform

This product includes software developed by the
Apache Software Foundation http://www.apache.org/

OS : windows xp
/***********************************************************/

That's all, sincerely look forward to your reply.

Original issue reported on code.google.com by [email protected] on 16 Nov 2012 at 1:58

Long.valueOf(0L) fail to compile

This gets converted to:

::java::lang::Long::valueOf(0LL)

which is missing a static_cast< int64_t >(0LL), making it ambiguous on 64-bit 
platforms with Long::valueOf(String*)

Original issue reported on code.google.com by [email protected] on 12 Jul 2013 at 1:33

linkage error

What steps will reproduce the problem?
1. I convert my Java app to C++ by J2C (that's fine)
2. I compile in CygWin (gcc (GCC) 4.7.3) the C++ version of my App (that's 
fine) 
3. But when I like to link, than raise an error message:

/home/kgy/cgyozo_cntan_baja_J2C/src/java/util/Arrays.cpp:1668:
 undefined reference to `Array<long long>::class_()'

The fwd-CNTAN_BAJA_J2C.hpp file with the next form included into Arrays.cpp: 

// Forward declarations for
#pragma once

#include <stdint.h>
#include <limits>

template<typename T> class Array;
typedef Array<bool> boolArray;
class boolArrayArray;
typedef Array<char16_t> char16_tArray;
class char16_tArrayArray;
class char16_tArrayArrayArray;
typedef Array<double> doubleArray;
class doubleArrayArray;
class doubleArrayArrayArray;
typedef Array<float> floatArray;
class floatArrayArray;
typedef Array<int16_t> int16_tArray;
class int16_tArrayArray;
class int16_tArrayArrayArray;
typedef Array<int32_t> int32_tArray;
class int32_tArrayArray;
class int32_tArrayArrayArray;

typedef Array<int64_t> int64_tArray;

class int64_tArrayArray;
typedef Array<int8_t> int8_tArray;
class int8_tArrayArray;
class int8_tArrayArrayArray;



****************************************************
Arrays.cpp:1668:
****************************************************

if(static_cast< ::java::lang::Object* >(eClass) == 
 static_cast< ::java::lang::Object* >(int8_tArray::class_()))
   npc(buf)->append(toString(java_cast< ::int8_tArray* >(element)));

else if(static_cast< ::java::lang::Object* >(eClass) == 
 static_cast< ::java::lang::Object* >(int16_tArray::class_()))
   npc(buf)->append(toString(java_cast< ::int16_tArray* >(element)));

else if(static_cast< ::java::lang::Object* >(eClass) == 
 static_cast< ::java::lang::Object* >(int32_tArray::class_()))
   npc(buf)->append(toString(java_cast< ::int32_tArray* >(element)));

**********
line 1668
else if(static_cast< ::java::lang::Object* >(eClass) ==  
 static_cast< ::java::lang::Object* >(int64_tArray::class_()))
**********
   npc(buf)->append(toString(java_cast< ::int64_tArray* >(element)));

else if(static_cast< ::java::lang::Object* >(eClass) == 
 static_cast< ::java::lang::Object* >(char16_tArray::class_()))
   npc(buf)->append(toString(java_cast< ::char16_tArray* >(element)));



****************************************************
int64_tArray.cpp
****************************************************
// Generated
#include <Array.hpp>

extern java::lang::Class *class_(const char16_t *c, int n);

template<>
java::lang::Class* int64_tArray::class_()
{
    static ::java::lang::Class* c = ::class_(u"long[]", 6);
    return c;
}

template<>
java::lang::Class* int64_tArray::getClass0()
{
    return class_();
}

Original issue reported on code.google.com by [email protected] on 30 Aug 2013 at 9:55

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.