Clojure custom Java Interop - java

I'm trying to find the best documentation and information on integrating custom Java files into a Clojure project. I've reviewed the project Enlight and see that the files are all .java files under the /src/main/java directory. Unfortunately it doesn't use Leiningen (what I'm using) so I can't see how it is called together the java files.
Suppose I want to use a big Java project from Clojure, like MALLET, which is abstracted into oblivion that a standard, major, main entry point like public static void main () cannot be found. Do I just dump every .java file into my classpath and hope for the best?

To include your own .java files in Leiningen project:
(defproject my-project "0.0.1-SNAPSHOT"
; ...
:java-source-paths ["src/main/java" "src_other/java"]) ; It's up to you how to structure paths
In this setup your .java files compilation will be managed by Leiningen.
To include existing Java project which is available in some of Maven repositories, just add dependency. For MALLET it will look like:
(defproject my-project "0.0.1-SNAPSHOT"
; ...
:dependencies [[cc.mallet/mallet "2.0.7"]])
Finally, if the goal is to include private jar file - the best option is to create local Maven repository.
In all of these cases you will be able to do normal Java <-> Clojure interop.

Related

how to include a java dependency for an R package

I have an R package that interacts with a java dependency (jar file) via the rJava package. I have no issues making things work when developing, but I don't know how to get the package installer to keep the jars with the installation in some sort of java src directory (e.g., file.path(.libPaths()[1], "mypackage", "java"). Is this possible without needing to write custom configuration files?
I am attempting to install using devtools::install_git. My source data is organized like most other R packages (I'm using the other features of devtools as well) except that I have an additional subdirectory java where my java dependencies are stashed.
Thanks
Keep the jar files in /inst/java and have something like the following in zzz.R
.onLoad <- function(libname, pkgname) {
.jpackage(name = pkgname, jars = "*")
}

Play Framework -- add new directories to classpath

I would like to be able to have a separate directory where jar files that represent plugins can be added to a Play 2.0 project.
Jar files are normally kept under the /lib directory in Play. I'd like to separate my jars in a directory called /plugins
This question was asked before, but the suggestion was to just use the /lib directory.
Adding additional java files to playframework classpath
Is there no way to do this without manually changing the 'eclipsified' files generated by Play?
I suppose you can do that by altering the sbt build script. Should be as simple as
unmanagedBase <<= baseDirectory { base => base / "custom_lib" }
Here is the link to the sbt documentation.

How to add directory to Clojure's classpath?

I have installed the libraries with Maven to the ~/.m2/repository/ directory. I would like to add that path to the default Clojure classpath. I could not find the documentation how to do that.
Any hints?
Cheers!
clj
Clojure 1.4.0
user=> (require '[clojure.java.jmx :as jmx])
FileNotFoundException Could not locate clojure/java/jmx__init.class or clojure/java/jmx.clj on classpath: clojure.lang.RT.load (RT.java:432)
The class path by default is:
user=> (println (seq (.getURLs (java.lang.ClassLoader/getSystemClassLoader))))
(#<URL file:/Users/myuser/cljmx/> #<URL file:/usr/local/Cellar/clojure/1.4.0/clojure-1.4.0.jar> #<URL file:/Users/myuser/cljmx/>)
nil
Leiningen really makes this process a lot less painful by keeping the setting of the classpath associated with the project, and more importantly leads to a repeatable build process. where you can come back to the project years later and still get a repl. A general outline of using leiningen in these cases:
lein new projectname
add the library you need to your project.clj file with a name you choose
run lein deps to print out the command to use to add the jar to your local repo
add the jar
run lein deps again (you can skip this step if using leiningen2)
run lein repl
enjoy
this is assuming that the library you are using is not already part of or available from a package in a maven repo, which many are.
The non-painful, popular method is to not mess with maven and classpaths and the JRE directly and use leiningen: https://github.com/technomancy/leiningen/
Otherwise, you can modify whatever is in clj and add/set the classpath in whatever ways java likes. See for example Setting multiple jars in java classpath
It should be noted that you also have the option of adding classpaths at runtime with the library pomegranate https://github.com/cemerick/pomegranate
This lets you do like:
(require '[cemerick.pomegranate :as pom])
(pom/add-classpath "/home/user/~.m2/....")
I assume that clj is a script to start Clojure REPL. Take a look into this script and find line similar to this:
java -cp /path/to/clojure.jar clojure.main
Here you start class clojure.main having "clojure.jar" on your classpath. To add more jars just add them to the end of -cp option values. E.g. on Linux:
java -cp /path/to/clojure.jar:/path/to/mylib.jar clojure.main
(use ; instead of : on Windows)
However, very soon you'll get tired of this way and will look for project management tool. So it makes sense to start using it right now. Take a look at Leiningen - it manages dependencies for you based on Maven (so it will be extremely easy to add new jar) and has REPL.
Another option is to create a deps.edn file in the folder where you plan to run the REPL or where you keep your project files.
This file is used to inform Clojure about dependencies, source files, execution profiles, etc… It's loaded when you run a REPL (but there are other use cases) and it's supported by the core of Clojure and it's officially documented on https://clojure.org/reference/deps_and_cli
In your case you may just want to put something like the following, to declare what dependencies you want to download and put on the Java classpath.
{
:deps {
the.dependency/you-want {:mvn/version "1.0.0"}
}
}
In deps.edn you can specify:
third party dependencies (eg JARs) that can be already saved locally, or hosted on a Maven repository, or on Git repository…
source paths, where your source code resides, if any
Note that the dependencies will be downloaded and cached in .cpcache/ folder, beside the deps.edn itself. I'm not sure if you can instruct it to use the global ~/.m2 instead.
You may find the dependency coordinates (name and latest version) on clojars.org
deps.edn is "lighter", part of the core Clojure, if less powerful than leiningen; so maybe suited for setting up an environment for casual/exploratory coding at the REPL or CLI.
You can also have a global deps.edn in ~/.clojure/deps.edn where you may want to define common configurations, dependencies, etc. to be used across different projects. Specific configurations can be invoked/overridden using options on the command line.

Java Project Compilation Errors

I have downloaded a complete package of Java product and trying to compile it using Ant. The project compiles with many errors, mostly related to imports starting with "org.apache.commons".
I'm new to Java. It looks to me that some system component is missing.
Some of the errors are:
package org.apache.commons.logging does not exist
package com.ibm.icu.text does not exist
cannot find symbol
What should I do to get rid of those errors?
As Sujee has said you need to include 2 jar files in your classpath. You can find the jars here:
http://download.icu-project.org/files/icu4j/4.4.1.1/icu4j-4_4_1_1.jar
http://apache.forthnet.gr/commons/logging/binaries/commons-logging-1.1.1-bin.zip
org.apache.commons.logging and com.ibm.icu.text are third party Java libraries. Download them from their websites and include in the Java classpath.
Update
Classpath is a list of file system paths which defines the locations of Java classes and libraries. JVM uses this to load the class it needs in the runtime. Usual practice is to put all libraries in a sub folder called 'lib' then add '\lib' in the classpath. My advice is to use a graphical tool like Eclipse so you don't need to manually do this. Please read this wikipedia article for more info about Classpath.

Recommended Source Control Directory Structure?

I am going to be using Subversion for source control on a new J2EE web application. What directory structure will you recommend for organizing code, tests and documentation?
I usually have
Project Directory
src - actual source
doc - documentation
lib - libraries referenced from source
dep - installation files for dependencies that don't fit in lib
db - database installation script
In work with Visual Studio, I'm not sure if this works the same in the java world. But i usually put stuff in different project folders in src. For each source project there's a separate test project. Build files go in the main project directory. I usually put a README there too documenting how to setup the project if it needs more than just checking out.
EDIT: This is the structure for a single working checkout of the project. It will be duplicated for each branch/tag in your revision control system (remember, in most SVN system, copies are cheap). The above example under Subversion would look like:
/project
/trunk
/src
/doc
/...
/branches
/feature1
/src
/doc
/...
/feature2
/src
/doc
/...
I found some old questions here on SO that might be interesting for you:
Whats a good standard code layout for a php application
Contains a link to an article on Scalable and Flexible Directory Structure for Web Applications (focus on PHP, though)
How to structure a java application, in other words: where do I put my classes?
Structure of Projects in Version Control
To expand on what Mendelt Siebenga suggested, I would also add a web directory (for JSP files, WEB-INF, web.xml, etc).
Tests should go in a folder named test that is a sibling of the main src folder - this way your unit test classes can have the same package name as the source code being tested (to ease with situations where you want to test protected methods or classes, for example... see the JUnit FAQ for this, and this question also on Where should I put my test files?).
I haven't had much use for it myself, but a Maven project will also create a resources folder alongside the src folder for non-source code that you want to package/deploy along with the main source code - things such as properties files, resources bundles, etc. Your mileage may vary on this one.
I use Eclipse for creating J2EE web applications and this will create the following project structure:
WebAppName\
\lib
\src
\tests
etc...
I would then create an SVN folder on our trunk called WebAppNameProject. Within this folder I would create folders called WebAppNameSource, Documentation etc. Within the WebAppNameSource folder I would place the project source generated by Eclipse. Thus I would have the following folder structure in SVN:
\svn\trunk\WebAppNameProject
\WebAppNameSource
\lib
\src
\tests
etc...
\Documentation
Hope this helps.

Categories