2

How can I import a library from maven central into a project with the ceylon import-jar command?

Please show the full command.

E.g. for "joda-time-2.9.4.jar" from "http://repo.maven.apache.org/maven2/" into a local directory.

I guess it must be:

./ceylon-1.2.3/bin/ceylon import-jar --rep  "http://repo.maven.apache.org/maven2/" --verbose --out localdir "joda-time:joda-time/2.9.4" "joda-time-2.9.4.jar"

But as far as I can see the tool is not working (ceylon versions 1.2.2 and 1.2.3).

Working with maven central is essential.

This question is linked with The ceylon copy tool because both tools present me with a riddle.

Community
  • 1
  • 1
  • Well, what I don't understand is *why* are you set on importing a Maven artifact in a Ceylon repository? Why can't you just let it be imported directly from Maven Central? But perhaps your use-case is special and unexpected (to us) so if you could explain *why* you want to do this it would help us answer your question. – Quintesse Jul 24 '16 at 22:22
  • Btw, as mentioned in a comment to the linked question about the copy tool: you shouldn't ever use `--rep "http://repo.maven.apache.org/maven2/"`. To access Maven Central `--rep aether:` is used and that's already activated by default so you don't need to specify it for any of the commands. – Quintesse Jul 24 '16 at 22:26
  • Please explain what you mean by "not working". At the moment it is kind of unclear. As another note, please rephrase your question as a question, not a statement. In its current form this question is unanswerable. – Roland Tepp Jul 25 '16 at 07:47
  • @Quintesse, the documentation about accessing legacy modules says "ceylon compile --rep aether:/path/to/special/setting.xml com.example.foo"; I.e. "aether:" is used as a prefix of setting.xml not as a prefix of the url of the repository. I think it might be good to have a bit more details about legacy repos. –  Jul 30 '16 at 07:22
  • @user3464741 Here is the documentation: http://www.ceylon-lang.org/documentation/1.2/reference/repository/maven/ – Quintesse Aug 01 '16 at 17:24

2 Answers2

0

1. As a (partial) answer to my question, this turned out to work:

$ ../bin/ceylon import-jar --rep flat:"../flat/" Jama/1.0.3 ../flat/Jama-1.0.3.jar

I downloaded the jar (in this case Jama-1.0.3.jar) by hand and then I was able to import it.

I had to try a lot to find out where to put the prefix "flat:", i.e. either to put it after "import" in the module descriptor "module.ceylon" or on the command line. The latter turned out to be the right choice.

But still, I haven't been able to find out how to import the jar from maven directly using the import-jar tool.

2. More detailed documentation is needed about managing modules. Specifically, there should be a clarification what the term "legacy repository" means.

Does "legacy" mean "deprecated"?

3. I hope that the following way to import dependencies into a project is not considered as "legacy" or "deprecated":

a) Rename the jar file, so that the name relfects the compressed directory structure within the jar.

b) Put the jar into a directory structure that again reflects the directory structure within the jar.

c) Put all that into the modules directory of the project, merging directories if necessary.

This seems to be the most explicit and reliable way to include dependencies into a project and I hope this way will not be deprecated or considered "legacy" at any time.

  • 1) The `--rep` option you give to the `import-jar` comment is useless, you can remove it without problem. – Quintesse Aug 01 '16 at 17:14
  • 2) No, that's not what legacy means, it means something pre-existing that is being supported but that does not itself form the basis for our future developments. We will indefinitely support Maven because it's an essential part of the Java ecosystem. – Quintesse Aug 01 '16 at 17:17
  • 3) Right now there are only two different kinds of layouts supported, the normal Ceylon hierarchical one that looks very much like Maven's hierarchy. Or the flat one where all modules are in a single directory. In both cases the name of the JAR file is fixed according to Ceylon's naming rules. – Quintesse Aug 01 '16 at 17:21
0

I understand you are asking about the ceylon import-jar tool specifically, but would like to offer a different solution that is easier if your goal is to import a jar from a remote repository.

I would suggest you use the Ceylon Gradle Plugin, which I wrote.

It knows how to grab dependencies from repositories (including JCenter and Maven Central, but many others), and it will run the ceylon -import-jar tool for you automatically.

Full Example:

  1. Run the following command to create a new test project (enter simple for the folder name):

ceylon new simple --module-name=com.athaydes.test --module-version=1.0

  1. Enter the new project name and have a look at what's in it (minimum Ceylon project):

cd simple

tree # or use Finder, Window Explorer or whatever

You'll see this:

    └── source
        └── com
            └── athaydes
                └── test
                    ├── module.ceylon
                    ├── package.ceylon
                    └── run.ceylon
  1. Edit module.ceylon so it has the following contents (add whatever dependencies you want):
    module com.athaydes.test "1.0" {
      native("jvm")
      import joda_time.joda_time "2.9.4";
    }

Notice the name of the module must be a valid Ceylon identifier! So, the Gradle plugin replaces invalid characters with _, generating a valid Ceylon identifier from the Maven artifact name.

  1. Create a build.gradle file at the root of the project so the Gradle plugin can work, with the following contents:
    plugins {
        id "com.athaydes.ceylon" version "1.2.0"
    }

    repositories {
        jcenter()
    }

    ceylon {
        module = "com.athaydes.test"
        flatClasspath = false
        importJars = true
        forceImports = true // necessary to bypass optional dependencies issues in Maven poms
    }

    dependencies {
        ceylonCompile "joda-time:joda-time:2.9.4"
    }

We must declare this dependency here as a normal Maven dependency so Gradle knows where to get the Jars from.

  1. Done... now just run importJars:

gradle importJars

Or, to just see the actual command generated (will not actually run it):

gradle -P get-ceylon-command importJars

Here's the generated command:

ceylon import-jar   
  --force  
  --descriptor=/Users/renato/programming/experiments/ceylon-gradle/simple/build/module-descriptors/joda_time_2.9.4.properties  
  --out=/Users/renato/programming/experiments/ceylon-gradle/simple/modules  
  --rep=aether:/Users/renato/programming/experiments/ceylon-gradle/simple/build/maven-settings.xml 
  --rep=/Users/renato/programming/experiments/ceylon-gradle/simple/modules
  joda_time.joda_time/2.9.4
  /Users/renato/.gradle/caches/modules-2/files-2.1/joda-time/joda-time/2.9.4/1c295b462f16702ebe720bbb08f62e1ba80da41b/joda-time-2.9.4.jar

The jars will be imported to the default location, modules (but you can configure that):

── build
│   ├── dependency-poms
│   │   └── joda-time-2.9.4.pom
│   ├── maven-repository
│   │   └── joda-time
│   │       └── joda-time
│   │           └── 2.9.4
│   │               ├── joda-time-2.9.4.jar
│   │               └── joda-time-2.9.4.pom
│   ├── maven-settings.xml
│   └── module-descriptors
│       └── joda_time_2.9.4.properties
├── build.gradle
├── modules
│   └── joda_time
│       └── joda_time
│           └── 2.9.4
│               ├── joda_time.joda_time-2.9.4.jar
│               ├── joda_time.joda_time-2.9.4.jar.sha1
│               └── module.properties
└── source
    └── com
        └── athaydes
            └── test
                ├── module.ceylon
                ├── package.ceylon
                └── run.ceylon

Now you can run the Ceylon code with the runCeylon task (or just run if there's no other task with this name):

gradle run

NOTE:

Unfortunately, actually importing the specific Jar you chose into the Ceylon repo is impossible with its original name... because in Ceylon, joda-time is an illegal identifier... so you need to change the name of the module when imported by Ceylon. The Gradle plugin does it for you.. but you need to know what the valid identifier will be to be able to write the import statement in the module file (you can just let the plugin run and it will tell you what the name will be).


A much simpler approach

If you want to avoid the complexity of this approach, you can just use the default Gradle plugin approach to NOT import Maven jars into the Ceylon repository and just use the simple Java classpath (which means you relinquish using the Ceylon modules system!).

If you do that, your build.gradle file will look like this:

plugins {
    id "com.athaydes.ceylon" version "1.2.0"
}

repositories {
    jcenter()
}

ceylon {
    module = "com.athaydes.test"
}

And the module.ceylon file:

module com.athaydes.test "1.0" {
  native("jvm")
  import "joda-time:joda-time" "2.9.4";
}

Notice that we don't need to mess up with the dependency name using this approach. From Ceylon 1.2.3, you should prepend the dependency with the maven: qualifier to avoid warnings.

That simple!

Renato
  • 12,940
  • 3
  • 54
  • 85