Building runnable jar with play framework [duplicate] - java

I'm trying to Play 2 application on Windows Server Server 2012 using the "stage" task, with the goal of wrapping this up in a service so the application will automatically run when the server gets restarted. However, when running the app I get the following message:
The input line is too long.
The syntax of the command is incorrect.
This is because Windows has a limit of around 8000 characters for command line instructions but it seems like the Play stage command is exceeding this by passing the classpath as an argument.
Copying the "stage" folder to c:\ might fix the issue (as it'll reduce the size of the classpath) but I was hoping there would be a more elegant solution.
Has anyone found a way around this? Alternatively, do people have any suggestions for running a Play application on Windows so that it will automatically run when the server is restarted.
Thanks.

I also had the same issue and I wasn't satisfied with the solutions that you provided.
I have found a simpler solution.
Add the following line to the build.sbt file
lazy val root = (project in file(".")).enablePlugins(PlayScala, LauncherJarPlugin)
Now if you generate your production application with:
sbt dist
or run a production mode with
sbt start
The LauncherJarPlugin plugin will take care for generating proper bash/batch run scrips.
To get to know more about LauncherJarPlugin please read the documentation:
Sbt documentation about long classpath
How to enable plugin in build sbt

UPDATE: sbt native packager now comes with a number of built in solutions to this, see NieMaszNic's answer below.
This is a known issue, being tracked in the SBT native packager (which generates the start script) here:
https://github.com/sbt/sbt-native-packager/issues/72
My recommendation to work around this issue would be to write your own start batch script that uses a wildcard classpath matcher. You can put this script in the dist directory in your Play project, and it will end up being packaged up with your application. That script might look like this:
java %1 -cp "./lib/*;" play.core.server.NettyServer .
Note that if you use a wildcard classpath matcher, you can no longer rely on classpath ordering to be the same as in dev mode. You shouldn't rely on classpath ordering anyway, but people inevitably do.

Taking James's suggestions into account, the following solution works for a Play 2 application.
CD into the app and run play clean stage
Copy [your_app]/target/universal/stage/bin/[YOUR_APP].bat to [your_app]/dist (you may need to create the "dist" directory). I renamed the file as [your_app]_windows.bat to make it clear but the name doesn't really matter. Files in the "dist" directory get copied across with your app the next time you run the stage task (thanks James).
Open your new bat file in a text editor.
Files put in the "dist" directory are put in the "universal" directory (not "bin") so you'll need to change the home variable, i.e. remove the two full stops at the end so it doesn't navigate to the parent directory (on line 11 at present),
e.g.
if "%WEB_PORTAL_HOME%"=="" set "WEB_PORTAL_HOME=%~dp0\\.."
becomes:
if "%WEB_PORTAL_HOME%"=="" set "WEB_PORTAL_HOME=%~dp0"
You then need to change the class path, as per James's instructions, to use a wildcard rather than explicitly listing all the JAR files (at the moment this is on line 91)
e.g.
set "APP_CLASSPATH=%APP_LIB_DIR%\web-portal.web-portal-1.0-SNAPSHOT.jar;%APP_LIB_DIR%\commons-c.....
becomes:
set "APP_CLASSPATH=%APP_LIB_DIR%\web-portal.web-portal-1.0-SNAPSHOT.jar;%APP_LIB_DIR%\\*"
You can then run your new script (which is copied into the [your_app]/target/stage/universal directory).
Important: I'd recommend re-creating this file every time you upgrade
Play just in case the build script changes in future releases.

Change the longest line in your bat file with:
set "APP_CLASSPATH=%APP_LIB_DIR%\..\conf\;%APP_LIB_DIR%\*"
just before
set "APP_MAIN_CLASS=play.core.server.ProdServerStart"

Enable LauncherJarPlugin first
lazy val root = (project in file(".")).enablePlugins(PlayJava, PlayEbean, LauncherJarPlugin)
Then if you want just to start play with production mode you can use activator :
activator clean compile stage testProd
or fast version :
activator testProd
This will run play in production mode, i'm not sure if you have to addstage to command because i'm pretty sure that its already building with testProd, but its better to make sure you built the stage version.

Related

ClassLoader.getSystemClassLoader().getResourceAsStream returns null after cloning Project

I've been applying the solutions from other similar questions.
I was getting a image from res folder using this line:
shell.setImage(new Image(display, ClassLoader.getSystemClassLoader().getResourceAsStream("icon_128.png")));
The file is inside "res" folder in the project.
It worked perfectly until I uploaded my project to a Git repo in Bitbucket. After cloning the project and importing it, now my project crash because getResourceAsStream("icon_128.png") returns null.
It's frustrating because it works perfectly in the other project which is not versioned into G|it, but crashes only in my cloned new directory project with Git.
In both versions of the project the file is inside the "res" folder.
What could be happening with this?
git has nothing to do with it. You didn't give enough detail to be sure about what's going on, but 2 obvious problems come to mind:
[1] getResourceAsStream looks for the named file in the same place that java looks for class files: The classpath. You're running this code either from an editor, or with java on the command line (in which case you're running a jar file and a build tool added a Class-Path entry to that jar, if you use the -jar switch, or you're not, in which case you're specifying the classpath on the command line), or with a build tool (in which case it will be supplying the classpath): icon_128.png needs to be in the root of one of the entries on the classpath, and now it isn't. The fix is to, well, fix that. Maven, for example, copies all resources find in /src/main/resources into any jars it makes. Your icon_128.png should be there.
[2] This isn't the right way to do it. The right way is ClassThisCodeIsIn.class.getResourceAsStream("/icon_128.png") (note: The starting slash; it is important). Your version has various somewhat exotic fail cases which this version skips. This version will look specifically in the classpath which produced your class file, and cannot NPE; your version will fail or throw NullPointerExceptions in various cases.
NB: When you cloned and re-built, the 'build' directories were effectively wiped because you don't check those into source control. That's why it worked before and doesn't now. git isn't to blame; you, or your IDE, copied icon_128.png to the build dir, and that step needs to be repeated every time you clone your git repo. A build tool automates this step and ensures that you can just do a fresh checkout from source control, and then invoke the build tool and all will be well after it finishes.

Eclipse keeps bin/META-INF/persistence.xml in use

On a clean installation of Eclipse Kepler 4.3.2, with an installation not including anything like JPA aspects, Spring, whatever - just plain Java, I keep encountering this weird issue.
Upon building the project, but not running it even once, the file bin/META-INF/persistence.xml is constantly in use. Eclipse refuses to rebuild the project because of it, and I can't delete the file while Eclipse is running.
This locking does not happen to any other (XML) file in the same folder, or any file in any other folder. Just that one file. Since Eclipse without any Hibernate or JPA tools installed should have no concept of the importance of this file, why does this happen? Not even the original source file is locked!
How can I debug this?
I presume you use Windows. Like jpangamarca mentioned, I have the same problem with Eclipse Luna and came up with a temporary solution before it is addressed by Eclipse itself.
How can I debug this?
I used Process Explorer to find out which process is locking my xml files. In the application, go to menu Find -> Find Handle or DLL... (Ctrl + F), fill in your file path, it will list all processes using your file. It is likely eclipse.exe in this case. You can then go back to the main screen, select the file in the lower panel and right click then choose Close Handle (or hit Delete).
I wrote a little batch file to do this conveniently whenever I feel necessary:
#echo off
for /f "tokens=3,6,8 delims=: " %%i in ('handle -p eclipse e:\git\ ^| grep ".xml\|.xmi\|.htm"') do echo Releasing %%k & handle -c %%j -y -p %%i
(replace e:\git\ with your path to limit scope of damage, using grep to only release locks on specific file types)
For the batch to work, you need the following utilities available in your system path:
Handle
grep
For windows with UAC (win 7/8), you will need to run it as administrator. Or else it will tell you to.
This happened to me and in my case the root cause was Hibernate JPA 2 Metamodel Generator: https://docs.jboss.org/hibernate/jpamodelgen/1.0/reference/en-US/html_single/
The only solution I found is to use EclipseLink's Canonical Model Generation https://wiki.eclipse.org/UserGuide/JPA/Using_the_Canonical_Model_Generator_%28ELUG%29
What worked for me (I'm working with an EAR project > EJB module) was moving all configuration files from prj-root/src/META-INF to a prj-root/resources/META-INF folder, then I modified my Ant script accordingly to generate the assemblies.
EDIT: This happens when using hibernate-jpamodelgen to generate the entities' static metamodel. Upgrade to at least 4.3.9 and you'll get rid of the problem (see https://hibernate.atlassian.net/browse/HHH-9528).
The handle script worked for me, but maybe it was my process i had to search for javaw instead of eclipse.

Java App unexpected behavior when exported

I have a very strange problem, that I can't figure out, the thing is that my aplication runs perfectly on the IDE (Eclipse), but not when exported, when I run the jar (double click) the aplication start but some functionality is missing (loading from a template file, but this does not happend when loading from a normal file), when I try to run it from console (java - jar my.jar) in order to see any error message it turns out that my aplication works perfectly fine! :S ...
Some more info:
My app is running over windows 7
I start the task manager, and I noticed that when I start my aplication using double click its under the name java.exe *32, and when I do it from command line its under the name java.exe (without "*32"), as far as I know I programmed nothing related to a 32 or 64 bits functionallity.
"Solved"
Well I was not able to solve it the way I wanted, as far as I was able to find, i found that there were a problem between the 2 java versions I was running x32 & x64, I deleted the 32 bit version and it start working as a charm, but I'm still not sure about what happend, I give my thanks to #Sajal Dutta one of its comments help me to understand part of the problem, thanks to all of you anyway, I'll keep searching until I find the problem...
When you create a jar from Eclipse, your assets don't get copied over to jar or location is not preserved. Open the jar and check if you have your templates in the right location or you have it at all.
To have the exported jar include your assets/resources-
Right click on your project in Eclipse. Then New -> Source Folder.
Name the source folder anything. e.g. template_src.
Copy or drag the entire directory of your template to template_src. Then make the jar.
Since it works via the command line but not when double-clicking the jar, it is likely that the working directory is different (and that you're loading the template with a relative path). When you run an executable jar by double-clicking, on some operating systems, the working directory is the home directory whereas when you run from the command line, it's the directory you're currently in.
The "files" in the jar are not handled by File, but are resources;
URL url = getClass().getResource("...");
InputStream in = getClass().getResourceAsStream("...");
Then, the file paths inside a jar, or on a non-Windows platform are case-sensitive.
"Template_A.xml"
is not
"template_a.xml"
Also you might inspect the jar with 7zip or WinZip.

Trying to remotely compile, using the command line, a Java program with multiple dependencies that I can currently only compile locally in Eclipse

Some weeks ago at work I took over a Java-based back-end web application written using Eclipse. The nature of the application is that it cannot be adequately tested locally, and instead changes need to be tested on our testing network (which involves pushing the changes to an AWS Micro server that we connect to via SSH).
Until now, I pushed changes in the same way as my predecessor: compile the program using Eclipse's Export to Runnable JAR File option, then scp the jar to the remote server and run it. However, this process has a huge problem. While compilation takes only seconds, the jar is well over 30MB, and pushing the entire thing from the office to the remote server over our fairly ordinary internet connection takes well over 10 minutes. If I'm having a particularly bad day and, say, introduce several minor bugs to the code and then discover them one by one, I can easily end up losing an hour or more in total twiddling my thumbs while pushing the whole jar over and over for a series of one-line changes.
Clearly, a saner solution than scping the entire jar for every change would be to simply remotely pull only the changed .java files from source control, and then compile the new version entirely remotely. However, I'm quite new to Java (and indeed programming generally) and all my Java work has been on existing Eclipse projects that I've taken over partway through development. As such, I know very little about compiling Java, and I have found the tutorials about this online are mostly either opaque or completely fail to address the question of how to compile code that uses external libraries.
I will relate here what information about the project's dependencies I can find from Eclipse, and my questions are these: what do I need to copy to the remote server, and where do I need to put it, to be able to compile remotely? What tools, if any, do I need to install on the remote server to be able to compile there? And once I've got everything set up, what do I actually type at the command line to get it to compile?
Anyway, here's what I know about the dependencies and directory structure (I've anonymised our application name by calling it “bunnies”):
The application source code is located in bunnies/src
We compile to bunnies/bin/main.jar
bunnies/dependencies contains three jars of external libraries that we use.
Right-clicking on the project in Eclipse, going to the Java Build Path section, and selecting the Libraries tab, I see
the three libraries above
(appearing in the form, e.g. “json-simple-1.1.1.jar - /home/mark/workspace/bunnies/dependencies”)
a fourth jar file in another location
(“M2_REPO/com/google/guava/guava/r09/guava-r09.jar - /home/mark/.m2/repository/com/google/guava/guava/r09/guava-r09.jar”)
JRE System Library [java-6-openjdk-i386]
But there's more! We also use two libraries, mahout-core and mahout-integration, that are included as separate projects in the same workspace rather than as jar files in the dependencies folder. They appear by name on the Projects tab of the Java Build Path section of the bunnies project, and are located at /home/mark/workspace/mahout-core and /home/mark/workspace/mahout-integration respectively.
Since I am not a Java whiz, perhaps there are also some other hidden dependencies I'm missing, that don't appear in any of the places I've looked so far?
If anyone can walk me through the steps of compiling this huge mess from the command line, without needing to use the Export option in Eclipse, so that I can ultimately compile it all remotely, I would be highly appreciative.
Look into Apache Ant. It's a build-suite for Java, sort of like an XML based Makefile system.
I have a Java system running on a remote server. I have a directory structure separated into /src and /build. I then just scp the .java files from my local machine to the /src folder and build using ant.

Eclipse create java executable with external libraries

I've seen this topic in this forum but it I need a more basic explanation on how to do this.
I've done a program in Java with some external libraries (LWJGL and Slick).
So this is what I've done and my program won't start anyway, tell me where I've done wrong.
I have Eclipse 3.7.1
My project is opened in Eclipse and runs well in Eclipse
I click File -> Export
I select Java -> Runnable JAR file
Here I don't know what to choose in Launch configuration, when I click the dropdown I get the option to choose my main class so I do that.
I select an export destination
I select the option "Package required libraries into generated JAR" under Library Handling
I don't know what ANT script is so I don't use that
I click Finish
I copy my images-folder to the same location as the generate JAR-file
I try to start the JAR-file, something loads in the background but nothing happens, no window shows up, nothing.
I check the Task manager in windows and sees that a javaw.exe is running
What did I miss?
My program uses images for graphics like this:
image = new Image("images/filname.png");
I wonder if I need to change the paths before exporting or the method to load these?
Thanks!
If you want to get things from inside a jar file you need to have them in your classpath and access them as resources.
The constructor you use, refers to a physical file which cannot peek inside a jar-file.
(EDIT) Also note that you have no guarantee where the current working directory is. Hence any relative references may break, as you see.
Read this to learn how to use JarSplice to export your Eclipse project to a runnable jar-file. Regarding images, you can put them in the same directory as a class file (in the jar) and then writeSampleClass.class.getResourceAsStream("image.png")to retrieve an InputStream of the image. Then you can load it however you like.
I had the same problem and I was able to fix it. All I did was copy the data folder (which contains my resources) into the *.jar file. You can do this for example with WinRAR.

Categories

Resources