I have a Java project that's paired with a bash script to make it easier to deploy on Linux. The script is a lot more complicated than this, but the part that matters is a section like this:
directory="/default/install/directory"
jarName = "myApp-0.0.1.jar"
command="/usr/bin/java -DARG=$argValue -jar $directory/$jarName"
When I update the version to 0.0.2, I would like maven to automatically change this line in my script, simply to:
jarName = "myApp-0.0.2.jar"
I'm sure this would involve maven-release-plugin in some way - possibly with sed -i, but my development machine is Windows so such tools are not so readily available (though I do use cygwin) - but I'm not really sure how. Thanks!
This is typically done by placing these kind of scripts as Maven resources.
Using Maven properties ('jarName = "myApp-${project.version}.jar"') instead of hardcoded values, and activating filtering on these resources will make this straightforward.
If these scripts should be packaged in a different way than just inside the JAR produced, the assembly plugin will be able to do the job.
Related
I have a simple pre-processing step that infrequently needs to be performed on some resources in a Maven/Eclipse project, this involves a simple OS command using a utility executable, for example:
glslc triangle.frag -o spv.triangle.frag
The glslc executable processes the triangle.frag shader module and generates the spv.triangle.frag output file (in the same directory).
Ideally I would like a maven goal that performed the above for all modified .frag files within a given directory structure, rather than having to switch to a terminal, or create shell scripts, etc.
I assume an ANT plugin for Maven is the way to go (assuming that's the simplest and most common mechanism available). I have tried adding a maven antrun plugin but I'm struggling to work out how to configure it for multiple/modified files. I'm sure it's relatively straight-forward but it's been a long time since I've had to fiddle with ANT and I'm at a bit of a loss where to start. Had a look online but can't find any decent examples or tutorials, probably because I'm not searching for the right things.
Note that the files do not change that much but it would be very convenient to have a quick-and-dirty (or hot-deploy) means of generating the output file file(s) that have changed.
Also note that these resources do not need to be part of the maven build/deploy process, i.e. they are only used during development and testing.
Alternatively is there an equivalent Eclipse mechanism that that can be used to do the same thing? Again this is a convenience so something relatively 'manual' is fine.
I'm looking for any pointers to relevant examples, tutorials, repos, etc. as a starting point or hint from which I can then implement a solution.
I would like to create a RPM package for my Java game (currently packaged as JARs + JNLP file). I use Ant as a build tool. I cannot use platform-dependent tools as the few developers who use my source code use several operating systems, not necessarily GNU Linux unlike me.
At first, I tried to use JDIC but its source code hasn't been maintained for years and I had to modify tons of things just to make it compile anew. Moreover, it just calls the native RPM tools under the hood. Then, I found RPM Ant task but it uses the native RPM tools under the hood too. After that, I found RPM Maven plugin but I don't want to switch to another build tool now just to create a RPM package.
Finally, I found Redline RPM pure Java library which has an Ant task, there is an example here. I still don't understand how to use it. I understand the role of a few basic fields (group, version, release, name), I know that I have to use "depends" to indicate that my game requires at least Java 1.7 but I don't know what to do with my JARs, where to put the .desktop file for the desktop shortcut and where to put the bash script that calls the main class to run my game. As a first step, I'd like to create a binary package. I have found another example using this library here. Do I have to provide an uninstall script too? Should I use a postinstall script to copy the .desktop file into the desktop directory? Should I use a tarfileset for the third party libraries? I know it would be better to put the JARs into several RPMs but I want to succeed in doing something simple before doing more elaborated but cleaner things.
I wrote a simple tutorial on how to use redline here
Basically everything you have to do build an empty rpm is that :
org.redline_rpm.Builder builder = new Builder();
File directory = new File(".");
builder.setType(RpmType.BINARY);
builder.setPlatform(Architecture.X86_64, Os.LINUX);
builder.setPackage("name", "1", "1");
builder.setDescription("Description");
builder.setSummary("Summary");
builder.build(directory);
You can add dependency on certain commands : example
builder.addDependencyMore("tar", "0");
builder.addDependencyMore("python", "0");
builder.addDependencyMore("wget", "0");
Then you can add some pre-install script or post-install script and files too.
builder.setPostInstallScript(xxx);
File tarball = new File("/the/dir/of/your/file/file.tar.gz");
builder.addFile("/where/to/put/it/file.tar.gz", tarball);
Redline maven dependency
<dependency>
<groupId>org.redline-rpm</groupId>
<artifactId>redline</artifactId>
<version>1.2.1</version>
</dependency>
I solved my problem here. I just have to add a short script to run the application.
P.S: By the way, I now use my own tool (which uses Redline RPM under the hood), it's fully documented, free software (under GPL) and works for DEB, APP and EXE (via NSIS) too, it's called Java Native Deployment Toolkit.
I have a project with a million jars (well, a lot). They came to me by maven, and I only use a small set of functionality. For cleanness sake, I was wondering with jars I could do without.
My first thought was to run the program with a code-coverage tool, and then find the classes that are touched.
Has anyone done this before? Or are there smarter tricks to achieve the same?
You can run the project using the -verbose:class VM option. This will print for all loaded classes where they are loaded from. Using some smart parsing app/grep/regexp will allow you to filter the jar names into a set of unique entries and tell you which are used.
I think this would be easier because it will automatically tell you if a class is used and if so in which jar.
Of course the problem with this and code coverage is that it will be possible that you delete a jar that is only used in some exceptional case, but your compiler will complain if you deleted one or two too many, leaving you with the (mostly not too complicated) task of finding which jar the class is in.
Possible suggestion when using linux:
java -verbose:class <your startup command here> | grep "\[Loaded" | grep -o "from .*\]" | cut -c 6- | sort | uniq
If you aren't using linux, then save to a file, get a linux machine and run on linux (or use something to run bash commands on windows)
Consider using a tool that already exists, like Dependency Finder or JDepend.
As with all static analysis tools, the use of reflection or DI frameworks can throw this off; I've resorted to custom tools that use this and other inputs to figure things out, although it's still static.
For full runtime usage info you can use Thirler's solution, although whether or not it's complete may depend on which code paths are followed.
You can use Maven Dependency Plugin for analysing your dependency tree. It will also suggest you the dependecies which are downloaded/added to your project because they are dependent to any other jars.
Do run a mvn dependency:tree and see if you are using few unrequired jars.
How do I import libraries in my Java program without using an IDE, like NetBeans?
In NetBeans I do it this way:
How can I achieve the same thing by just using Notepad++ or Programmer's Notepad.
As much as possible I don't want to use NetBeans because it would be overkill since I'm only working on simple projects.
Use:
javac -classpath external.jar myClass.java
If your main class is in a package,
package com.mycompany;
public class myClass
{
...
...
then you'll need
javac -classpath external.jar com/mycompany/myClass.java
And to run:
java -classpath external.jar com.mycompany.myClass
In addition to Bala R's post, adding multiple files and locations is perfectly OK too...
javac -cp location1/;location2/;file1.jar;file2.jar fileToCompile
Notes:
-cp and -classpath are the same thing.
If you're on Solaris (and some other Unix flavors), change the ';' to ':'.
All of the other posters are spot on; you just need to add the JAR file to your classpath.
Java offers many mechanisms for setting the classpath, including via the command line, via an environment variable, and through setting it in the MANIFEST.MF of an executable Java JAR file.
These are all a pain in the neck to manage. It's good to know the technique, and understand the basics. But it's really a bad idea to actually use them.
You should do this.
First, put all of your Java libraries in a single place on your system. C:\java\libraries, or whatever. Someplace that you remember, and someplace accessible by all of your projects.
Next, name all of your libraries using their version numbers. If you using Log4j v1.4.1, then put the JAR file in a log4j-1.4.1 directory in your library area. This gives you "free" library versioning.
Finally, learn Ant. For simple projects, Ant is simple. Use the Ant build.xml file to compile, test, and run your application.
Why? Several reasons.
Because once it's set up, adding a new library to your project is trivial; you add a line to your build.xml file. Ant lets you more easily handle simple abstractions (like where all of your libraries are located).
The build.xml file is self-contained. If you use, say, an environment variable for the classpath, then the classpath for one project may be different from that of another. That means resetting the environment variable. Continue this and you'll end up swearing at some "new problem" where it "worked before" when it's because you had your classpath set wrong. Set it once in the build.xml file, and forget it.
Ant is portable. It runs the same on Windows, on Linux, on Mac, on AS/400, it runs everywhere that Java runs, unlike shells scripts or BAT files.
It's lightweight. Simple Ant scripts are simple. They don't bring a lot of baggage with them, and you can always make them scary complicated. It's much simpler than Maven for just builds.
Most IDEs support Ant directly. If you decided to go back to an IDE, most can simply use your Ant build file with minimal configuration.
This is how you solve your classpath problem with Notepad++. Setting the classpath works, but it doesn't go far enough. It's a pain to administer and manage. Learning the basics of Ant will take you much farther with minimal work.
You should put them on your classpath, like
java -classpath someJar.jar YourMainClass
And, of course, you can do the same for javac.
If you need to have more than one JAR file or directory on your classpath, you'll need to use your platform's default path separator. For example, on Windows,
java -classpath someJar.jar;myJar.jar YourMainClass
On a side note, you might find it easier to use an IDE to manage this sort of stuff. I've personally used just my slightly scriptable editor and have managed fine. But it's good to know how to do this stuff by the command line.
Put the JAR files in your classpath. classpath is an environment variable.
Make sure the JAR file is in your classpath and you have the import statement.
I have a java application from which I build a jar that relies on many third party jars, what's the best/common way of packaging this application for end user distribution?
The best way is to use a build tool like Maven2 or something similar, and use that to manage your dependencies and build a all-in-one package.
Otherwise, you'd mostly be stuck with messing with manifest files. Although, IDEs like Eclipse or NetBeans may help you a bit with that.
The way packaging is done. There are two ways
wrap as executable: This is common, if you know the supportable platform and wrap the Jar in executable. And distribute it. Something like this http://launch4j.sourceforge.net/ (I have not used this, but there are similar wrapper available)
Bundle all Jar and provide script: You can use Maven's Assembly plug-in to bundle everything in one Jar. With this done, you can distribute with a bat file and a .sh file for Windows and Linux based systems respectively. If you see Glassfish is distributed in similar manner. These scripts has executable command and, often take parameters for different behaviors.
You can also use Fat Jar Eclipse Plug-In
OR
Packaging and Deploying Desktop Java Applications in NetBeans