We are working on Java Maven project. We are dealing with database to get their schema. One of them is Sybase database, so we generate its ddl using DDLGen command line utility. To use ddlgen, I have imported these three jars in my code and added them into class-path in running jars:
jconn4.jar
DDLGen.jar
dsparser.jar
After that, we have used following code to generate DDL:
String command = "java -cp \"myPath\\lib\\com\\jconn4\\4.0\\jconn4-4.0.jar;myPath\\lib\\com\\dsparser\\4.0\\dsparser-4.0.jar;myPath\\lib\\com\\DDLGen\\4.0\\DDLGen-4.0.jar\" com.sybase.ddlgen.DDLGenerator -UuserName -Ppassword -SconnectionString -DdatabaseName -OoutputFile";
try {
Runtime run = Runtime.getRuntime();
Process pr = run.exec(command);
pr.waitFor();
} catch (Exception e) {
//errors
}
This code working fine when jars are found at path in their respective folders (hard-coded) : myPath\lib\com
On building the project, this structure will be changed, like all jar used in project will be put into path ....myProject/repo/alljars
Then ddlgen should have to be changed like :
String command = "java -cp \"repo\\jconn4-4.0.jar;repo\\dsparser-4.0.jar;repo\\DDLGen-4.0.jar\"
BUT this is not a correct solution to change the path every time, when code running using IDE and with build.
I just want an solution that these jar files should be searched into project path whether from IDE or build, then above given jars should be added into classpath in -cp command, then it should execute ddlgen.
Thus is there any way to achieve my requirement?
It seems when your program is run the jconn4-4.0.jar, etc. are already in classpath.
In that case, you do not need to launch another copy of the jvm, you can instead simply execute the Main method of the class as follows:
com.sybase.ddlgen.DDLGenerator.Main(
"-UuserName", "-Ppassword", "-SconnectionString", "-DdatabaseName" "-OoutputFile")
As a bonus, you would also be able to catch any exceptions thrown, instead of having to parse the output from the other jvm.
Related
After mvn install to generate jar. Can not Loader.loadNativeLibraries() on windows.
The version of ortools is 9.0.9048. I used it on windows.
I added the following two jar to the project and I added them as the link said.
Then the two jar is in here of the IDEA.
The pom file is the following:
Then I can run the program normally in IDEA. But when I mvn install to generate the jar file and run the jar by 'java -jar jarfile.jar', it errors as:
It said java.nio.file.NoSuchFileException: /BOOT-INF/lib/ortools-win32-9.0.jar!/win32-x86-64/, but when I open the jar in winrar, it exists.
Does anyone know the reason?
An example of Mac version.
You need two jars when using ortools in Java actually, ortools-java-9.0.9048.jar and ortools-darwin-x86-64-9.0.9048.jar. The two jar is unzipped from the official file and they are in the main directory.
ortools-java-9.0.9048.jar is the algorithm package which you do not need to care to much. Adding dependency to your program is all of you need to do.
The key is the ortools-darwin-x86-64-9.0.9048.jar. The following code is to read this jar to finally call the algorithm in ortools-java-9.0.9048.jar:
import com.google.ortools.Loader;
Loader.loadNativeLibraries();
It usually works well in IDEA. But when you package the code to a jar file, error happens because of Loader.loadNativeLibraries(); can not find the file in the ortools-darwin-x86-64-9.0.9048.jar.
The solution is to unzip ortools-darwin-x86-64-9.0.9048.jar and get the absolute path of libjniortools.dylib(if you are using linux, it will be a file similar as libjniortools.so and a file similar as libjniortools.dll in Windows). And using the following code instead of Loader.loadNativeLibraries();
System.load("Absolute path/libjniortools.dylib");
It will work after you package your code by this method.
The official artifacts are:
groupe: com.google.ortools, artifact: ortools-java
https://search.maven.org/artifact/com.google.ortools/ortools-java/9.0.9048/jar
For macOS, you can try this code, similar like #Muz solution
public static void loadOrToolLibrary() {
String os = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH);
if (os.equals("mac os x")) { // only for MAC local
File file = new File("src/main/resources/macosLocal/libjniortools.dylib");
String absolutePath = file.getAbsolutePath();
System.load(absolutePath);
} else {
Loader.loadNativeLibraries();
}
}
Below is my sample class file:
package org.foo.tutorial;
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
}
In order to execute the project (maven framework) we run:
>java -cp Something-1.0.SNAPSHOT.jar org.foo.tutorial.APP
The above command works fine and gives me the output 'HELLO WORLD'.
However, if I leave out the third argument in the above command (org.foo.tutorial.APP) I get the following error:
Error: Could not find or load main class target.MavenTutorialApp-1.0-SNAPSHOT.jar
My question is:
Why should the groupId and app name matter when I am supplying the entire 'jar' file ?
The error is a bit misleading. Your java command is incorrect since you don't specify a class. The Something-1.0.SNAPSHOT.jar is meant to be part of the -cp option but java is interpreting it as the class.
That's how java behaves
The java command starts a Java application. It does this by starting a
Java runtime environment, loading a specified class, and calling that
class's main method.
If your .jar file contains an entry point specified by a Main-Class header in the manifest, then you can simply run
java -jar Something-1.0.SNAPSHOT.jar
Let me try to answer your question.
Why should the groupId and app name matter when I am supplying the
entire 'jar' file ?
Lets divide the question into smaller part -
What is group id? - The id of the project's group.
What is artifactId? - The id of the artifact (project) and off course version is part of default artifact name.
While running a java program under jvm there are no such effect that how you built jar, for example it is produced by maven or gradle build process or even command line.
Things that matter is jar file and entry point or the class where main reside.
This may be out of scope of this question, but i felt relevant.
To run java program from jar file, you can explicitly mention like above. Also you can create executable jar file by adding manifest file, where it define the entry point of the executable -
Main-Class: org.foo.tutorial.APP
How to create executable jar?
Also maven maven-assembly-plugin helps to package executable jar.
help
I want to use clearNLP (http://clearnlp.wikispaces.com/) for extracting semantic role labels of an input sentence. I followed the instructions here: http://clearnlp.wikispaces.com/installation (I downloaded the jar files, put them in a directory called ClearNLP and set the classpath) but when I run the command java com.clearnlp.run.Version, I face the error: Could Not find or Load Main.
I tried it twice: Once I set the classpath as an environment variable of windows and ran the command in CMD. But, when it didn't work, I tried to create a java project, set the libraries using NetBeans and run the program. But, it didn't work, too.
BTW, when I run echo %classpath% command, I see that the classpath is set correctly.
Can anybody help me?
Try Eclipse. I included the jars in a new project I created. I then created a simple class like so
package test;
import com.clearnlp.run.Version;
public class TestClearNLP {
public static void main String(args[]) {
Version.main(args);
}
}
When run, this creates output in the console of:
ClearNLP version 2.0.2
Webpage: clearnlp.com
Owner : Jinho D. Choi
Contact: support#clearnlp.com
The only weird situation I ran into was that Eclipse did not like the jar files beginning with a period. I removed those from my project and ran with the remaining libraries.
I just export my java project to executable jar. I have somehow made my project work to access value from DB (hibernate.cfg.xml), config.properties, and log4j.properties & editable for future...
I want to put hibernate.cf.xml, config.properties and log4j.properties in the outside of jar and place them somewhere in other directory.
I've been search for this and got this way :
Created a /path/to/mydir directory at some place in my deployement system.
Moved log4j.properties and META-INF and hibernate.properties and hibernate.cfg.xml to mydir.
and use this command
this is just example:
java -cp Myjar.jar:/path/to/mydir MyMainClass
the command that I write is like this:
java -cp coreservice.jar:/mon/properties CoreServiceController.java
I've try like that way but i got this error
Error: Could not find or load main class
anyone can help me to fix it or give the better way will be pleasure ~
====================(EDIT)===================================================
Oh my god ~
I have delete(cut) folder META-INF from my jar and paste to my config folder (/mon/properties)
and try this command again java -cp coreservice.jar;mon/properties/ id.co.bn
i.coreservice.controller.CoreServiceController..... annnndddddd this work ;))
tha-nks for Apostolos, Antoniossss, Yasa and no name :)
You should not use
java -cp coreservice.jar:/mon/properties CoreServiceController.java
you should put the class file there and try again, not the source java file
if this is in package let's say com.test, then in parent directory of com/test you type
java -cp coreservice.jar:. com.test.CoreServiceController.
this should work
(Edit) to load hibernate.cfg.xml file from specific location, try this method inside your HibernateUtil class:
public static void setConnectionProperties() {
URL configFileURL = null;
try {
configFileURL = URL_OF_YOUR_CFG_XML_FILE;
configuration = (new Configuration()).configure(configFileURL);
sessionFactory = configuration.buildSessionFactory();
} catch (HibernateException e) {
e.printStackTrace();
System.out.println("Error while initializing hibernate: " + e.getMessage());
}
}
If I right understood your question:
When you configure sessionFactory you can write so
new Configuration()
.configure("/path/to/your/files/hibernate.cfg.xml")
.buildSessionFactory();
full example
So as you have still the same problem than I must say that you are doing something very very wrong, because this is the very basics of java runtime. Principles:
Definetly you have to provide fully qualified class name for java to run, not source file (*.java) so your call has to be proper.package.CoreServiceController
CoreServiceController cannot be in default page (no package name specified) - if it does, create some package just for test eg. service.core and put CoreServiceController there. As for point 1 - your call will be java -cp coreservice.jar:/mon/properties service.core.CoreServiceController nothing more, nothing else.
Java has nasty behaviour if you provide wrong entry for classpath - it does not say that eg. file myUberProgram.jar does not exists etc. It will just ignore such entry and go on. I had similar issues on Linux with CP - mispelled jar file and "what the hell is going on here?! Why is it not running" - same problem as you have - no class found
Check to be 101% sure, if there is CoreServiceController.class file in your jar file - maybe something wrong is with the packaging, and there is no such file in jar.
Finally, if all previous restrictions are fulfilled and nothing works, last chance for you, is to navigate to change working directory to one that jar file is in (simply go there from command line) and try tu run application without external cp provided. From directory where jar is:
Call java -cp Myjar.jar proper.package.CoreServiceController - should work but next one is 100% checked
Call java -cp ./Myjar.jar proper.package.CoreServiceController - all my applications on remote Linux server are lunched from bash scripts just like that and it always works.
If none of this helped you, than I must say dump your mashine into the ocean because it is cursed or something xD - I just want to say, that I have no other ideas how to help you.
For your practice build simple HelloWorld jar and try to lunch it from command line (but not runnable jar so you will have to provide classpath). Maybe in this way you will se what you did wrong.
My thinking is done for today, good day sir!
PS. #splatter_fadli I allowed myself to edit your question becouse as for now it is missguiding - you dont have problem with H configuration, only with running app while multiple entries in class path are provided. Maybe it will be accepted. - Aaaaaand it is done.
Last stand edit:
According to this question - QA put classpath entry into commas. Try it out. If Class not found will be gone, than we are half way there. -cp "coreservice.jar:/mon/properties"
I'm pretty new to Perl but have been programming in java for several months now (coming from a C++ background). I wrote a Perl script that parses some data logs and now the customer I'm working for wants a GUI. The GUI has been created as a java applet (using Netbeans) and I would like to "embed" the perl script inside its jar file as a default safety feature. Multiple updates are expected for the perl script later in the future, so I want to set it up so that all the user has to do when an update comes along is define a new file path to the latest perl script through the GUI. I've already implemented this functionality with a file browser and everything works fine.
The problem I'm running into is something very simple that's probably not very hard for someone with more java experience. Just in case one of the updated perl scripts they receive in the future doesn't work properly, I want them to be able to use the default "embedded" script if they have to resort to that. When I'm running the applet through Netbeans, everything works perfectly however when I try and run the jar file from the command line, the program returns an error saying it cannot find the file. I might not be using the correct terminology to search for a solution to this problem, but I would like to be able to have my jar file execute the embedded perl script at runtime. Any suggestions are appreciated. I've tried placing the perl file in the same package as the java files and calling for the script by its filename alone, but that was a no go.
You can access any file in the jar as a classpath resource, but the problem you're going to have is users may not have a perl interpreter installed.
EDIT: Since you've mentioned that users will have a Perl runtime, then this is doable. You can try piping the contents of the file using Process.getOutputStream() or just copy the contents to a temp file with File.createTempFile() and pass that file name as an argument to the perl interpreter.
I have the same problem, here's how I solved it based on Josh and Jiggy's discussion above. First look for the file in src/main/resources/perl (so it works in Eclipse). If it does not exist then copy the Perl file from the perl directory inside the jar to src/main/resources/perl. I building with Maven so using the src/main/resources/perl directory means when I build the jar, Maven automatically includes the perl directory in the jar.
This is a similar strategy to the one used to load resources from jars such as properties files.
I am using this approach because I have a multi-module Maven project when each submodule builds a jar. We have one that does general information extraction, then another one that specializes that module for a particular client. The Perl code lives inside the general module, but it is needed in the specialized one. Copying files between modules in Maven is rather awkward, so it is easier just to put it in resources, then let the Java code solve the problem.
See this related question for a good answer of an alternative approach to embedding native code such as C in jars.
The code looks like this (I'm using Apache Commons IO):
public class PerlTableParser {
private static final String RESOURCES_DIR = "src/main/resources";
private static final String LIB_PATH = RESOURCES_DIR + "perl/";
private static final String PERL_PARSER = "perl/parser.pl";
private static final String PERL_CMD = String.format("perl -I %s %s",
LIB_PATH, RESOURCES_DIR + PERL_PARSER);
public PerlTableParser() {
File perlCodeDir = new File(LIB_PATH);
if (!perlCodeDir.exists()) {
perlCodeDir.mkdirs();
}
File perlParserFile = new File(RESOURCES_DIR, PERL_PARSER);
try {
if (!perlParserFile.exists()) {
FileUtils.copyInputStreamToFile(getClass().getClassLoader()
.getResourceAsStream(PERL_PARSER), perlParserFile);
}
} catch (IOException e) {
MyLogger.logger.error(
"Failed to copy Perl code to local directory " + e, e);
}
}