I left an open issue for here
I´m trying to create a custom codegen, I managed to make it work by putting the files inside of the codegen project but I want it to work like this: https://github.com/swagger-api/swagger-codegen#making-your-own-codegen-modules
I haven't modified the autogenerated project at all but I keep getting:
Error: Could not find or load main class io.swagger.codegen.SwaggerCodegen
This is the command line:
java -cp output/myLibrary/target/myCustomCodegen-swagger-codegen-1.0.0.jar:swagger-codegen-cli-2.1.6.jar io.swagger.codegen.SwaggerCodegen generate -i https://watson-api-explorer.mybluemix.net/listings/conversation-v1-experimental.json -l com.my.company.codegen.Mycustomcodegengenerator -o outputlocation
I got the jar from here https://mvnrepository.com/artifact/io.swagger/swagger-codegen-project/2.1.6
This is what I'm doing:
Run java -jar swagger-codegen-cli-2.1.6.jar meta \ -o output/myLibrary -n myClientCodegen -p com.my.company.codegen to create costume codegen
Run mvn package in output/myLibrary
Run java -cp output/myLibrary/target/myCustomCodegen-swagger-codegen-1.0.0.jar:swagger-codegen-cli-2.1.6.jar io.swagger.codegen.SwaggerCodegen generate -i https://watson-api-explorer.mybluemix.net/listings/conversation-v1-experimental.json -l com.my.company.codegen.Mycustomcodegengenerator -o outputlocation in the folder that contains both swagger-codege-cli-2.1.6.jar and the output folder
It does find the class if I remove the first part, but doesn´t find the new language:
java -cp swagger-codegen-cli-2.1.6.jar io.swagger.codegen.SwaggerCodegen generate -i https://watson-api-explorer.mybluemix.net/listings/conversation-v1-experimental.json -l com.my.company.codegen.Mycustomcodegengenerator -o outputlocation
I have looked at the answers for "Error: Could not find or load main class" problems but haven't manage to fix it.
Here is a link to the jar
For Windows, change the colon (:) to a semicolon (;) - between the jars in the class path. So instead of
java -cp output/myLibrary/target/myCustomCodegen-swagger-codegen-1.0.0.jar:swagger-codegen-cli-2.1.6.jar io.swagger.codegen.SwaggerCodegen generate -i https://watson-api-explorer.mybluemix.net/listings/conversation-v1-experimental.json -l com.my.company.codegen.Mycustomcodegengenerator -o outputlocation
It should be
java -cp output/myLibrary/target/myCustomCodegen-swagger-codegen-1.0.0.jar;swagger-codegen-cli-2.1.6.jar io.swagger.codegen.SwaggerCodegen generate -i https://watson-api-explorer.mybluemix.net/listings/conversation-v1-experimental.json -l com.my.company.codegen.Mycustomcodegengenerator -o outputlocation
Multiple class paths need to be separated by a semicolon. http://docs.oracle.com/javase/7/docs/technotes/tools/windows/classpath.html
The problem is that you don't specify that correct path of swagger-codegen-2.1.6.jar in your call. Thats why it can't find the main-class.
If you are inside the root project swagger-codegen you should specify it like this: modules/swagger-codegen-cli/target/swagger-codegen-cli.jar
~$ cd ~/git/swagger-codegen # go into your root project
~/git/swagger-codegen$ # ... do the steps you described
~/git/swagger-codegen$ java -cp \
output/myLibrary/target/myClientCodegen-swagger-codegen-1.0.0.jar:modules/swagger-codegen-cli/target/swagger-codegen-cli.jar \
io.swagger.codegen.SwaggerCodegen \
generate -i https://watson-api-explorer.mybluemix.net/listings/conversation-v1-experimental.json \
-l com.my.company.codegen.Mycustomcodegengenerator \
-o outputlocation
Or as a one-liner:
~/git/swagger-codegen$ java -cp output/myLibrary/target/myClientCodegen-swagger-codegen-1.0.0.jar:modules/swagger-codegen-cli/target/swagger-codegen-cli.jar io.swagger.codegen.SwaggerCodegen generate -i https://watson-api-explorer.mybluemix.net/listings/conversation-v1-experimental.json -l com.my.company.codegen.Mycustomcodegengenerator -o outputlocation
Update 1
I'm pretty sure when you construct the classpath with -cp you have a mistake with the swagger-codegen-cli-2.1.6.jar. Please test the following.
Copy both (myClientCodegen-swagger-codegen-1.0.0.jar and swagger-codegen-cli-2.1.6.jar) jars into the same folder. Then go into this folder and try the following:
javap -cp myCustomCodegen-swagger-codegen-1.0.0.jar:swagger-codegen-cli-2.1.6.jar io.swagger.codegen.SwaggerCodegen
javap checks whether the main class io.swagger.codegen.SwaggerCodegen is available. On my machine it prints this:
Compiled from "SwaggerCodegen.java"
public class io.swagger.codegen.SwaggerCodegen {
public io.swagger.codegen.SwaggerCodegen();
public static void main(java.lang.String[]);
}
I had this similar problem when running as Spring Boot app in Eclipse 4.19 in macOS 10.14:
"Error: Could not find or load main class
io.swagger.Swagger2SpringBoot"
…even as I was staring at this very class containing the main method. My solution was issuing a "maven update project". This, like in other situations with odd Java symptoms, fixed the issue.
Related
Let's say we have the following Dockerfile for the purpose of creating a java image and compiling two scripts.
FROM openjdk:latest
COPY src JavaDocker
WORKDIR JavaDocker
RUN mkdir -p bin
RUN javac -d bin ./com/myapp/HelloWorld1.java
RUN javac -d bin ./com/myapp/HelloWorld2.java
WORKDIR bin
ENTRYPOINT java
How can I run any of these two scripts that have been compiled?
I'm using the command: docker run myapp-image "com.myapp.Server"
And I get:
Usage: java [options] <mainclass> [args...]
(to execute a class)
or java [options] -jar <jarfile> [args...]
(to execute a jar file)
or java [options] -m <module>[/<mainclass>] [args...]
java [options] --module <module>[/<mainclass>] [args...]
(to execute the main class in a module)
or java [options] <sourcefile> [args]
(to execute a single source-file program)
Arguments following the main class, source file, -jar <jarfile>,
-m or --module <module>/<mainclass> are passed as the arguments to
main class.
I'd suggest building a separate image per application; that can help clarify what the image is supposed to do. I also generally recommend using CMD over ENTRYPOINT.
So a Dockerfile that runs only the first application could look like:
FROM openjdk:latest
# Prefer an absolute path for clarity.
WORKDIR /JavaDocker
# Set up the Java class path.
RUN mkdir bin
ENV CLASSPATH=/JavaDocker/bin
# Use a relative path as the target, to avoid repeating it.
# (If you change the source code, repeating `docker build` will
# skip everything before here.)
COPY src .
# Compile the application.
RUN javac -d bin ./com/myapp/HelloWorld1.java
# Set the main container command.
CMD ["java", "com.myapp.HelloWorld1"]
What if you do have an image that contains multiple applications? If you use CMD here, it's very easy to provide an alternate command when you run the image:
docker run myapp-image \
java com.myapp.HelloWorld2
# Wait, what's actually in this image?
docker run --rm myapp-image \
ls -l bin/com/myapp
I generally recommend reserving ENTRYPOINT for a wrapper script that does some first-time setup, then runs exec "$#" to run a normal CMD. There's an alternate pattern of giving a complete command in ENTRYPOINT, and using CMD to provide its arguments. In both of these cases ENTRYPOINT needs to be JSON-array syntax, not shell syntax.
ENTRYPOINT ["java", "com.myapp.HelloWorld1"] # <-- JSON-array syntax
CMD ["-argument", "to-program-1"]
docker run myapp-image \
-argument=different -options
but it's harder to make that image do something else
docker run \
--entrypoint ls \ # <-- first word of the command is before the image name
myapp-image \
-l bin/com/myapp # <-- and the rest after
docker run \
--entrypoint java \
myapp-image \
com.myapp.HelloWorld2
Your original Dockerfile will probably work if you change the ENTRYPOINT line from shell to JSON-array syntax; using shell syntax will cause the CMD part to be ignored (including a command passed after the docker run image-name). You might find it easier to make one complete application invocation be the default and include the java command if you need to run the other.
I am working with the following example: https://github.com/caplin/jnijnaexamples/tree/master/jna
In mac, I could create the .dylib file as follows:
gcc -shared -fpic -o librandomjna.o randomjna.c
g++ -dynamiclib -undefined suppress -flat_namespace *.o -o librandomjna.dylib
mkdir classes
javac -d classes -classpath jna-4.4.0.jar JavaNativeAccess.java
cd classes
export LD_LIBRARY_PATH=.
java -classpath jna-4.4.0.jar:. com.enlightedinc.apps.where.utils.JavaNativeAccess
In OSx, it works as expected and able to execute the C function list_files
Now in Linux Box, I created the .so file as follows
gcc -shared -fpic -o librandomjna.o randomjna.c
gcc -shared -o librandomjna.so *.o
In the same way, new classes are generated in Linux mkdir classes
javac -d classes -classpath jna-4.4.0.jar JavaNativeAccess.java
cd classes
export LD_LIBRARY_PATH=.
java -classpath jna-4.4.0.jar:.
com.enlightedinc.apps.where.utils.JavaNativeAccess
now when I try to execute the code in this Ubuntu box, I get following error
Exceptionjava.lang.UnsatisfiedLinkError: Error looking up function 'randomNumber': ./librandomjna.so: undefined symbol: randomNumber
What can possibly go wrong ?
Whats the difference between .dylib and .so file ?
Why .dylib (mac osx) can resolve all function calls , whereas .so file (linux) fails to look up the function ?
Any help will be highly appreciated.
Thanks
Kaniska
First of all, try following:
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:.
Then, make sure your so file contains what you expect
nm librandomjna.so | grep rand
finally, I solved the problem by generating the .so file directly from the .c file
gcc -shared -fpic -o librandomjna.so randomjna.c
now .so file contains all the symbols.
I've been trying to make opencv for linux, I used the cmake parameters:
cmake -D CMAKE_BUILD_TYPE=RELEASE -D WITH_OPENCL=OFF -D BUILD_PERF_TESTS=OFF -D BUILD_SHARED_LIBS=OFF -D JAVA_INCLUDE_PATH=$JAVA_HOME/include -D JAVA_AWT_LIBRARY=$JAVA_HOME/jre/lib/amd64/libawt.so -D JAVA_JVM_LIBRARY=$JAVA_HOME/jre/lib/arm/server/libjvm.so -D CMAKE_INSTALL_PREFIX=/usr/local
and it generated the files fine.
It was then into around the 81% when it was trting to generate the opencv-jar it opped up with
/home/pi/Desktop/opencv-3.1.0/modules/java/generator/src/cpp/common.h:8:17 fatal error jni.h No such file or directory
So I'm not sure what to be doing now with it. openjdk is installed properly too
Edit: I tried using the -I flag, by doing the command
make -I/usr/lib/jvm/java-8-openjdk-armhf/includes
to no avail
the -I flag on make(1) command only affects the files included in the makefile by the .include directive, not the directories searched for by the compiler. For that purpose, just pass the -I flag to each compilation. One way to do this is
$ make CFLAGS="-I/usr/lib/jvm/java-8-openjdk-armhf/includes"
you can also pass the CFLAGS from the environment, as in
$ export CFLAGS=\""-I/usr/lib/..."\" # escaped double quotes make them to be included in the string.
$ make
Please check: https://stackoverflow.com/a/67154438/1290868
FindJNI
find_package(JNI)
if (JNI_FOUND)
message (STATUS "JNI_INCLUDE_DIRS=${JNI_INCLUDE_DIRS}")
message (STATUS "JNI_LIBRARIES=${JNI_LIBRARIES}")
endif()
I am trying to run the WordCount example. But I am facing issues with compiling the program.
I get the error:
error: package org.apache.hadoop.mapred does not exist
after executing:
javac -classpath /usr/local/hadoop/share/hadoop/common/hadoop-common-2.7.3.jar -d wordcount_classes WordCount.java
I set up hadoop using this tutorial. I also looked this up on stackoverflow : question and executed the bin/hadoop classpath command in /usr/local/hadoop. This is the output I obtained:
/usr/local/hadoop/etc/hadoop:/usr/local/hadoop/share/hadoop/common/lib/* :/usr/local/hadoop/share/hadoop/common/* :/usr/local/hadoop/share/hadoop/hdfs:/usr/local/hadoop/share/hadoop/hdfs/lib/* :/usr/local/hadoop/share/hadoop/hdfs/* :/usr/local/hadoop/share/hadoop/yarn/lib/* :/usr/local/hadoop/share/hadoop/yarn/* :/usr/local/hadoop/share/hadoop/mapreduce/lib/* :/usr/local/hadoop/share/hadoop/mapreduce/* :/contrib/capacity-scheduler/*.jar
But I don't know what to make of it or what my next step should be! Please help!
You're trying to compile the source code using one of the many hadoop dependency jars (hadoop-common-x.x.x.jar). The jar that contains the mapred package noted in the error message is the hadoop-mapreduce-client-core jar.
I suggest you use a build tool such as Maven or Gradle to build your source code as it will manage transitive dependencies for you.
Alternatively to proceed with your manual invocation of javac, try something like this (untested):
javac -cp '/usr/local/hadoop/share/hadoop/common/*' \
-cp '/usr/local/hadoop/share/hadoop/hdfs/lib/*' \
-cp '/usr/local/hadoop/share/hadoop/hdfs/*' \
-cp '/usr/local/hadoop/share/hadoop/yarn/lib/*' \
-cp '/usr/local/hadoop/share/hadoop/yarn/*' \
-cp '/usr/local/hadoop/share/hadoop/mapreduce/lib/*' \
-cp '/usr/local/hadoop/share/hadoop/mapreduce/*' \
-d wordcount_classes WordCount.java
I am trying to call a java program in php to use it with web interface.
Java program is dependent on an external lib: commons-cli-1.2.jar
So basically I need to export it before calling the java program; but if I export it first as:
shell_exec('export CLASSPATH=$CLASSPATH:~/lib/commons-cli-1.2.jar');
then call the java program as:
shell_exec('java ComputePagerank -i $para_i -d $para_d -e $para_e -o $para_o');
I think it creates different shells for each call; then the export does not have any effect on java program. Or am I wrong?
Otherwise, it should output a file in the server. But simply it does not. So, what is wrong? Any idea?
edit: However can it be because some parameters such as para_i stands for an input file name, so that i have to specify full path for that? Because I just assume if the input file is in the same working directory, there won't be any problem, will it?
edit-2: it outputs properly when i use command line;)
you're right, each shell_exec creates a separate shell.
env CLASSPATH=whatever java -switches
I would use
shell_exec('java -cp $CLASSPATH:/home/yourname/dir/lib/commons-cli-1.2.jar ComputePagerank -i $para_i -d $para_d -e $para_e -o $para_o > message');
and (this is important) replace the tilde(~) with the actual path to your directory (/home/yourname say). The ~ is expanded by the shell and is dependent on which shell you''re using.
Try Creating a simple shell script with the commands that you want to execute. You may pass arguments to a shell script so that is not a problem either.
for example
echo "Running Script..."
java -cp $CLASSPATH:~/lib/commons-cli-1.2.jar ComputePagerank -i $1 -d $2 -e $3 -o $4 > message
etc.
Then try calling it from the command line first with some parameters. Did it output? Then try calling it from the php script. Did it output? If it did not then you may need to check permissions. I had a simiolar experience some time ago with a Java program that simply did not have permission to write a file.
You should be able to call it like this.
shell_exec('java -cp $CLASSPATH:~/lib/commons-cli-1.2.jar ComputePagerank -i $para_i -d $para_d -e $para_e -o $para_o > message');
Another option is to issue the 2 commands seperately, but to the same shell, like this:
shell_exec('export CLASSPATH=$CLASSPATH:~/lib/commons-cli-1.2.jar; java ComputePagerank -i $para_i -d $para_d -e $para_e -o $para_o > message');
edit:
some shells don't let you call export while you're setting up the variable. so this may be safer than the second option above:
shell_exec('CLASSPATH=$CLASSPATH:~/lib/commons-cli-1.2.jar; export CLASSPATH; java ComputePagerank -i $para_i -d $para_d -e $para_e -o $para_o > message');
another edit:
If none of the above work then you're going to have to do some more trouble shooting. Does your java program work from the command prompt?
java -cp $CLASSPATH:/home/user/lib/commons-cli-1.2.jar ComputePagerank -i param1 -d param2 -e param3 -o param4 > message