Including local jar file in Clojure project - clojure

I have used the leiningen plugin localrepo to install my own java class as a jar file. This seems to have worked fine since it gets installed into ~/.m2 as evident by the command below.
lein localrepo list | grep myJunk
$ myJunk/exp (1.0.0)
I then include the following line in project.clj
[myJunk/exp "1.0.0"]
Finally I include the following in my .clj file.
(ns exp.exp-test
(:use [exp.core]
[clojure.test])
(:import [com.curry.expenses Expense]))
When I try to run the import i get the following error:
java.lang.ClassNotFoundException: com.curry.expenses.Expense
This is the beginning of my java class from which I have generated the jar file.
package com.curry.expenses;
public class Expense { ... }
Now my question is what am I missing in order to be able to use this class in my Clojure project?
Update:
This is the content of the generated .pom file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>myJunk</groupId>
<artifactId>exp</artifactId>
<version>1.0.0</version>
<name>exp</name>
</project>

Ok, So we spotted at least one error.
You have a project and inside that project is a class FooBar.java with a namespace foo.bar.baz then it is expected that the file Foobar.java is in a folder structure like this: foo/bar/baz mirroring the namespace, most probably lying in a src folder.
Generating a jar from that will also have that path inside the jar and inside the path under foo/bar/baz will be the FooBar.class.
This is nothing specific to clojure but to java in general and clojure expects the same folder structure.

Related

Building docker image for multi module project pushing jars to classpath

I am trying to create docker image for my project which is having multiple modules. The need is to build the image in such a way that the image should contain the child module jar in a given classpath. The structure of my project is
parent_project
|
|
module-1
|
pom.xml
|
module-2
|
pom.xml
|
pom.xml
So ideally when the build happens it the image should have a classpath where both modules jar are to be present. But with the below given pom.xml I am seeing the images when build are overwritten with latter build. So one image is build with first module jar and second image is formed with second module jar thus final image contains only the later jar.
part of pom.xml
<modules>
<module>xxxxxxxxx_m1</module>
<module>xxxxxxxxx_m2</module>
</modules>
<build>
<plugins>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>1.8.0</version>
<configuration>
<from>
<image>xxxyyyy****_base_image</image>
</from>
<container>
<entrypoint>INHERIT</entrypoint>
<appRoot>/etc/plugin</appRoot>
<environment>
<CLASSPATH>
/etc/plugin/classpath/xxxxxxxxx_m1-SNAPSHOT.jar
/etc/plugin/classpath/xxxxxxxxx_m2-SNAPSHOT.jar
</CLASSPATH>
</environment>
</container>
<containerizingMode>packaged</containerizingMode>
</configuration>
</plugin>
</plugins>
</build>
I am building the image by providing following command :-
mvn package jib:build -Dimage=<base_image>:<tag_name>
Your project setup makes sense only when each of the two modules xxxxx_m1 and xxxxx_m2 is a standalone app that has its own main class and can run independently of each other, each with
java -cp <xxxxx_m1-SNAPSHOT:others...> <main class in xxxxx_m1>
java -cp <xxxxx_m2-SNAPSHOT:others...> <main class in xxxxx_m2>
That is, the setup makes sense only when you intend to create two separate and independent images for two different apps. In this case, Jib is working as intended and you are producing two different container images. It's just that by saying -Dimage (equivalent to -Djib.to.image), you are giving the same target image name for the two images, so one ends up overwriting the other in the end, which doesn't make sense. If this is really the case, you just need to define <to><image> differently in each module. (You can have <pluginManagement> in the root pom.xml to declare Jib version and common Jib <configuration>, and then define module-specific Jib <configuration> in each sub-module pom.xml. I will point you to an example at the end, so keep reading.)
But I am not sure if this is what you intended, because it sounds like you want to see both modules inside a single image. Perhaps it's that _m2 is the app with a main class and _m1 is a JAR library that _m2 depends on? (That is, pom.xml in _m2 defined _m1 as a dependency?) In this case,
root pom.xml: define <pluginManagement> to declare the Jib version
_m1 pom.xml (dependency library): set <skip>true to suppress Jib image building
_m2 pom.xml: optionally define _m2-specific configuration
Take a look at this multi-module example. It has three modules, where Jib runs in hello-service and name-service to build two images, while name-service defines the shared-library module as a dependency.
In either case, I don't see a reason to set <containerizingMode>packaged or <environment><CLASSPATH> unless your app is specifically written to read the environment variable or requires to run inside a JAR (e.g., need to read JAR manifest). The default "exploded" containerizing mode is much more efficient, so just try running Jib without these.

Can't run clj file cause "couldn't locate" in cljs+clj project

I have 2 project: my backend on Clojure and frontend on ClojureScript.
I decided to merge them. So i copied files from both projects, runed lein deps and try to start my backend. So i got this error
Couldn't locate web.clj on classpath
In my project source-paths:
["src/clj" "src/cljs"]
And main ^:skip-aot clj.web
My frontend is working properly.
My folder structure:
src
clj
web.clj
cljs
*some cljs files*
So how can i setup my source-paths setting to run my backend?
The namespace you want to start is not clj.web but web so your project.clj file should have:
main ^:skip-aot web
And your web.clj file should being with:
(ns web)
If you use subfolders in the future, the namespaces will be mapped with the following rules:
(ns com.my-company.clojure.examples.my-utils)
The ns form names the lib’s namespace and declares its dependencies. Based on its name, this lib is typically defined in a source file at the classpath-relative path: com/my_company/clojure/examples/my_utils.clj (note the translations from period to slash and hyphen to underscore).

"WARNING: JBIG2ImageReader not loaded." but [org.apache.pdfbox/jbig2-imageio "3.0.1"] exists?

My project is building with Leiningen using the pantomime 2.10.0 library [com.novemberain/pantomime "2.10.0"] which is some Clojure wrapper for Apache Tika. I ground through some documentation at https://pdfbox.apache.org/2.0/dependencies.html to attempt to eliminate WARNings emitted by org.apache.tika.config.InitializableProblemHandler but one seems to persist.
Sep 06, 2018 1:59:25 PM org.apache.tika.config.InitializableProblemHandler$3 handleInitializableProblem
WARNING: JBIG2ImageReader not loaded. jbig2 files will be ignored
See https://pdfbox.apache.org/2.0/dependencies.html#jai-image-io
for optional dependencies.
I am struggling to understand what else I have to add to my project.clj dependencies to get this warning to go away. Why didn't [org.apache.pdfbox/jbig2-imageio "3.0.1"] satisfy the dependency.
The relevant portions of my project.clj's :dependencies are:
[org.xerial/sqlite-jdbc "3.23.1"]
[org.apache.pdfbox/jbig2-imageio "3.0.1"]
[com.github.jai-imageio/jai-imageio-core "1.4.0"]
[com.github.jai-imageio/jai-imageio-jpeg2000 "1.3.0"]
[com.novemberain/pantomime "2.10.0"]
What did I miss?
To disable these warnings you need to suppress them in Tika config file.
tika.xml:
<?xml version="1.0" encoding="UTF-8"?>
<properties>
<service-loader initializableProblemHandler="ignore"/>
</properties>
and then use this config file in your code:
(let [handler (BodyContentHandler.)
config (TikaConfig. (FileInputStream. "tika.xml"))
parser (AutoDetectParser. config)
metadata (Metadata.)
stream (FileInputStream. "resources/memory.pdf")]
(.parse parser stream handler metadata)
(prn (str handler)))
To enable support for JBIG and everything you should refer to tika-parsers-1.17.jar!/META-INF/maven/org.apache.tika/tika-parsers/pom.xml which holds all the references to the supported plugins along with their versions. Add those plugins to your dependecies.
For the [com.novemberain/pantomime "2.10.0"] you should go with
[com.levigo.jbig2/levigo-jbig2-imageio "1.6.5"]
[com.github.jai-imageio/jai-imageio-core "1.3.1"]
[com.github.jai-imageio/jai-imageio-jpeg2000 "1.3.0"]
It works for Java 1.8, but I believe it won't work for Java 1.10, which has this new module thing now. One of these plugins doesn't support this.

make cppcheck skip the PACKAGE definition

I'm using the GUI version of cppcheck 1.64 for static code analysis on C++-Builde-6 code. For DLL exports and imports, the definition of PACKAGE is necessary:
/// A dialog exported from a BPL (a VCL-specific kind of DLL)
class PACKAGE MySharedDialog {
public:
// lots of methods to-be checked
private:
// lots of methods to-be checked
// lots of members
};
Cppcheck stops when it encounters PACKAGE because it doesn't know what it means:
The code 'class PACKAGE TAppInfoDialog {' is not handled. You can use -I or --include to add handling of this code.
...and this of course means that the entire class isn't checked. If I could make cppcheck simply ignore the PACKAGE "keyword", it would do exactly the right thing, but how to do it? Including its original definition via include path, seems to be not an option: cppcheck then tells me a lot about headers of the VCL framework I cannot change...
The manual does not describe an option to do it, Google doesn't help, SO does not have an answer yet.
In the cppcheck issue tracker, I found the analogous problem #4707 (Microsoft 'abstract' and 'sealed' extension for class) – cppcheck. Here the lead developer suggests to create a file and (pre-?)include it to the cppcheck run, but I'm using the GUI version and there is no option to include a single file. So I tried to add a directors to the include section of my project options (an XML file), then I edited the corresponding line to a file specification, but that's clearly nonsense, because this section contains include paths.
What can I try next?
A solution is to add the definition of PACKAGE (being empty) to the project file:
<?xml version="1.0" encoding="UTF-8"?>
<project version="1">
<defines>
<define name="PACKAGE=" />
</defines>
</project>
This solution I finally found in this small but valuable project file description at the project repo cppcheck/gui/projectfile.txt at master · danmar/cppcheck · GitHub

Hudson build fail: Non-resolvable parent POM

I used to work with Hudson on my project, and lately I had to move it to a new server.
I configured it the exact same way it use to be (for all I can tell) but when I try to launch a build, it fails and I get the following error:
Démarré par l'utilisateur anonymous
Checking out http://[...]/trunk/MyProject/ear
A .classpath
A .project
A target
AU target/ear-1.0-SNAPSHOT.ear
A target/application.xml
A target/ear-1.0-SNAPSHOT
A target/ear-1.0-SNAPSHOT/META-INF
A target/ear-1.0-SNAPSHOT/META-INF/application.xml
AU target/ear-1.0-SNAPSHOT/web-1.0-SNAPSHOT.war
AU target/ear-1.0-SNAPSHOT/business-1.0-SNAPSHOT.jar
A pom.xml
A .settings
A .settings/org.eclipse.jdt.core.prefs
A .settings/org.maven.ide.eclipse.prefs
At revision 136
no change for http://[...]/trunk/MyProject/ear since the previous build
Found mavenVersion 3.0.2 from file jar:file:/usr/share/maven/apache-maven-3.0.2/lib/maven-core-3.0.2.jar!/META-INF/maven/org.apache.maven/maven-core/pom.properties
Parsing POMs
ERROR: Echec à la lecture des POMs
org.apache.maven.project.ProjectBuildingException: Some problems were encountered while processing the POMs:
[FATAL] Non-resolvable parent POM: Could not find artifact com.rha:MyProject:pom:1.0-SNAPSHOT and 'parent.relativePath' points at wrong local POM # line 9, column 10
at org.apache.maven.project.DefaultProjectBuilder.build(DefaultProjectBuilder.java:325)
at hudson.maven.MavenEmbedder.buildProjects(MavenEmbedder.java:360)
at hudson.maven.MavenEmbedder.readProjects(MavenEmbedder.java:330)
at hudson.maven.MavenModuleSetBuild$PomParser.invoke(MavenModuleSetBuild.java:1148)
at hudson.maven.MavenModuleSetBuild$PomParser.invoke(MavenModuleSetBuild.java:991)
at hudson.FilePath.act(FilePath.java:756)
at hudson.FilePath.act(FilePath.java:738)
at hudson.maven.MavenModuleSetBuild$RunnerImpl.parsePoms(MavenModuleSetBuild.java:698)
at hudson.maven.MavenModuleSetBuild$RunnerImpl.doRun(MavenModuleSetBuild.java:531)
at hudson.model.AbstractBuild$AbstractRunner.run(AbstractBuild.java:420)
at hudson.model.Run.run(Run.java:1362)
at hudson.maven.MavenModuleSetBuild.run(MavenModuleSetBuild.java:405)
at hudson.model.ResourceController.execute(ResourceController.java:88)
at hudson.model.Executor.run(Executor.java:145)
Finished: FAILURE
The pom.xml file when I got to Hudson "workspace" looks like this:
[...]
<parent>
<groupId>com.rha</groupId>
<artifactId>MyProject</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
[...]
<dependencies>
<dependency>
<groupId>com.rha</groupId>
<artifactId>business</artifactId>
<version>1.0-SNAPSHOT</version>
<type>ejb</type>
</dependency>
<dependency>
<groupId>com.rha</groupId>
<artifactId>web</artifactId>
<version>1.0-SNAPSHOT</version>
<type>war</type>
</dependency>
</dependencies>
</project>
[Edit]
Actually I forgot some important informations:
My project is divided into 3 parts:
business (packaged into .jar)
web (packaged into a .war)
ear (packaged the .war and .jar into a .ear)
I'm using Subversion, and under my "trunk" folder I got a "MyProject" folder including:
.project
.settings/
business/
ear/
pom.xml
src/
web/
what happens is:
in my Hudson job configuration, I filled the SVN field "repository URL" with:
http://[...]/trunk/MyProject/ear
and here is the "pom.xml" from "MyProject" folder:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
[...]
<modules>
<module>business</module>
<module>web</module>
<module>ear</module>
</modules>
[...]
so the parent "pom.xml" is actually located at "../pom.xml" on my SVN repository, under "trunk/MyFolder".
But Hudson can't see it for some reason (but like I said, it used to work on the previous server).
Any clue ?
[/Edit]
I guess this is a rookie mistake, I'm a total beginner on Maven, but I just can't figure out why it's not working anymore ...
Any help will be greatly appreciated !
Nicolas
relativePath (of the parent) defaults to ../pom.xml. It looks like it is not present in there. You could set it to an empty value so that maven downloads it as a dependency.
<relativePath/>
This link discusses this.
[Edit: based on the edits to the question]
Hudson only sees the source code inside ear folder. Though the parent pom is present in SVN, it is not available to Hudson. Missing parent pom was aa warning in Maven 2 but strict in Maven 3.
There are two ways to solve this.
One is to specify to hudson, the url http://[...]/trunk/MyProject/. You can then chose to build all the modules or still choose to build the pom.xml of ear project alone.
The other is to manually run mvn install on the hudson system so that the parent pom gets deployed once and thereafter used by hudson. However, this will not get updated if parent pom is subsequently changed.
Retrieving the Root-POM from the Maven-REPO should usually also work (like you do), but I would expect you havn't triggered the root pom to be installed into the REPO on the new hudson site so far.
To avoid this use the relativePath property, e.g. something like this:
<relativePath>../pom.xml</relativePath>
in your <parent> tag which will tell maven to look for the root pom in your module structure.
I had the same problem with Hudson, Sonar plugin and a multi-module Maven project: "Non-resolvable parent POM" when Hudson tried to run sonar:sonar. The solution was to specify the Root POM location in the Hudson job configuration under the Sonar section.
The project structure in SVN (each one is a Maven project with pom.xml in the project root):
foo-parent
+- foo-ui-module
+- bar-other-module
I have individual Hudson jobs for each project, "foo-parent", "foo-ui-module" and "bar-other-module". The Sonar run in a Hudson job could not find the parent POM even though the build was successful until that point. Maybe the Sonar plugin doesn't use the same Maven settings as the rest of the job because it didn't try to look for the parent POM from our Artifactory repository, not even with <relativePath/> in the project POM.
The place for the Root POM setting was under the job's Configure -> Sonar -> Advanced -> Root POM: ../foo-parent/pom.xml (I have foo-parent job at this path)
We managed to get this working by simply deleting the relevant pom file, plus some sort of metadata file with a similar name in the same folder, from the .m2/repository/a/b/c folder on our jenkins server.
Rerunning the jenkins build after doing this worked just fine.
Hope this helps someone...