dcsimg
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 7 1234 ... LastLast
Results 1 to 15 of 95

Thread: TIP: Packaging your Java applications for other people

  1. #1
    Join Date
    Oct 2003
    Location
    .NET2.0 / VS2005 Developer
    Posts
    7,104

    TIP: Packaging your Java applications for other people

    Search keywords: jar manifest cvfm packaging internet explorer navigator TOTALJARSOLUTION

    I worked through this as a favour for a codeguru user, and thought i would pass the tip on


    What is it about?

    Packaging your application. How to go from a bunch of class files to a file that you can run easily on most systems; as easy as an EXE


    How To Do It

    When you have your program fully compiled and working, you can do several things. I'll run through all of them:

    1) Turn your app into a jar file that you can double click on to run (just like exe)
    2) Turn your app into a jar file, then write a batch file to run it (for older systems)
    3) Turn your applet into a jar file and get it running on all browsers, including the applet viewer

    The jar file is the common element here, so lets do it:



    1) Making a .jar

    A jar IS a zip file, with a .jar extension. It groups all your files (no matter what.. source, class, gif, jpeg, wav, readme, etc) into one easy to handle file
    On new versions of java, you double click the .jar and the program runs. Simple as that.

    jar involves use of the command line, but first, lets arrange the directories nicely:

    Make a folder somewhere, call it FINAL
    Inside FINAL, make a folder called APP
    Inside APP, copy all the files your program needs, along with their directories
    Inside FINAL, create a new text document, called mf.txt
    -(file menu>> new>> text document).
    --Is the file called New Text Document.txt? Read on..
    --Or, is the file called New Text Document only.. NO .txt? Follow the instructions under this link. It is VERY important that you do so now, before proceeding.

    Open the mf.txt and write on the first line: Main-Class: MYCLASS (and press return)
    -Substitute MYCLASS for the name of your application (i.e. what you run to make it go. If you type java DataViewer on a command promt, then put Main-Class: DataViewer in the mf.txt
    -DO NOT put the .class extension. (Do not write Main-Class: DataViewer.class)
    -you MUST press return, so that there is at least one blank, empty line at the end of the manifest file, otherwise the text on that line wont be read

    Open a command prompt
    -winxp/nt/2k: Start>> Run>> CMD (return)
    -win95/98/me: Start>> Run>> COMMAND (return)

    Change directory to the APP folder (inside FINAL folder)
    -(your FINAL folder is on D: drive, in "javawork" folder, then you type D:(return) followed by cd D:\javawork\FINAL\APP(return)

    Jar the files, using mf.txt as the manifest:
    -type jar cvfm ..\MYAPP.jar ..\mf.txt .
    -substitute MYAPP for a nicer name. If your app was called DataViewer you might want to say: jar cvfm ..\dv.jar ..\mf.txt .
    --explanation: cvfm= (c)reate jar (v)erbose output (f)ilename of jar [is specified] (m)anifest file [is specified]
    --the double periods .. mean "the parent directory", hence the jar file is placed alongside APP, not within it.
    --the final period . means "the current directory". Jar understands this to be the base point for your files.

    Check that the jar file works:
    -go to the parent directory, by typing cd .. (you should now be in the FINAL directory)
    -type java -jar MYAPP.jar, substituting, of course, the nice name for the jar (e.g. java -jar dv.jar)

    If all goes well, your app will start. If you get a message saying something like: NoClassDefFoundError: MYAPP\class.class then you need to edit the word .class out of the manifest file (thats what happens if you put it in.. java thinks it has to look for a file called CLASS in a folder called MYAPP)
    -if the NoCLassDefFoundError looks more like: NoClassDefFoundError: MYAPP.class then are you SURE that the class called MYAPP.class is in the APP folder? (and not some other folder)
    -check that the main class (MYAPP.class in my example) is in APP folder, and not within a subdirectory of APP folder

    Close your app, and exit the command line
    In the FINAL folder, you can now delete mf.txt and folder APP (so long as its not the only copy of your program! Move it away if it is!)
    You are left with just the jar file. I'll assume it is called MYAPP.jar
    If you have java 1.4, you can just double click that jar to run the file.


    One important issue here, is that JAR files are understood by java to be a filesystem of their own and like UNIX/LINUX, the filenames are case sensitive! Windows doesnt care for case sensitivity.
    This has implications, as you will see, because when you are putting your files in jar files, it is down to Java (not windows) to get them out!
    As a result, if your java program uses ANY external resources like icons, pictures, mp3, midi files, text files, xml files.. you MUST get the EXACT same name in the java source, as you do on the disk.
    Example: If your sourcecode looks like this:
    Code:
      ImageIcon ii = new ImageIcon("images/MyIcon.GIF");
    and your file is called "myicon.gif", then it WILL work before you put everything in the jar, but it WONT work after!




    2) BAT files

    BAT files are a bunch of MS-DOS commands in one file. You write one as if you were writing a load of commands on the command line, and it works the same.
    Make a New Text Document like before, only this time rename it to go.bat
    -Windows asks you if you want to change the extension. Say yes.

    Right-click your go.bat file and choose EDIT

    In notepad, write the following text (only the bold bits):
    java -jar MYAPP.jar substituting MYAPP for your jar's name
    pause on the next line. Pause will prevent the window from going away if there are error messages

    That's it!

    If you run that batch file now, your java program will run. The batch file needs to be kept alongside the jar file (in the same folder), or windows wont find it
    If you dont want to see the DOS window when you run your app, use javaw instead of java (w = window mode)


    3) Running your applet jar file in all browsers

    For this, your app needs to be an Applet. That is, the main class must be declared like:
    public class MYAPP_MAIN extends Applet{}

    There is more to converting an app to an applet (and many reasons for not doing so) than i will detail here. This section is for people who are already aware of how to make an applet

    Once upon a time, it was simple. We used the applet tag and it worked. Then IE thought it would be better to use OBJECT, and Navigator thought it would be better to use EMBED
    We can get round this easily.

    Choose File>> New>> Text Document
    Open the new text document (we will rename it to html later, for now, leave it as text)

    Paste the following code into the text document, and change the CAPITAL LETTER sections:
    Code:
    
    <html><head><title>PUT THE TITLE OF YOUR WINDOW HERE</title></head>
    <body><center>
    <OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
        width="800" height="650" align="baseline"
        codebase="http://java.sun.com/products/plugin/autodl/jinstall-1_4-windows-i586.cab#Version=1,4,0,0">
        <PARAM NAME="code" VALUE="PUT YOUR MAIN CLASS NAME HERE; INCLUDE THE .CLASS EXTENSION">
        <PARAM NAME="java_archive" VALUE="PUT YOUR JAR NAME HERE; INCLUDE THE .JAR EXTENSION">
        <PARAM NAME="type" VALUE="application/x-java-applet;jpi-version=1.4">
        <PARAM NAME="scriptable" VALUE="true"> 
        <PARAM NAME="PUT YOUR FIRST CUSTOM PARAM NAME IN HERE" 
               VALUE="PUT YOUR FIRST CUSTOM PARAM VALUE IN HERE">
        <PARAM NAME="PUT YOUR SECOND CUSTOM PARAM NAME IN HERE" 
               VALUE="PUT YOUR SECOND CUSTOM PARAM VALUE IN HERE">
        (And so on, for all other parameters your applet needs)
    
        <COMMENT>
            <EMBED type="application/x-java-applet;jpi-version=1.4" width="800"
               height="650" align="baseline" 
               code="PUT YOUR MAIN CLASS NAME HERE; INCLUDE THE .CLASS EXTENSION" 
               archive="PUT YOUR JAR NAME HERE; INCLUDE THE .JAR EXTENSION" 
               java_archive="PUT YOUR JAR NAME HERE; INCLUDE THE .JAR EXTENSION"
               CUSTOM_PARAM_NAME1 = "CUSTOM_PARAM_VALUE1"
               CUSTOM_PARAM_NAME2 = "CUSTOM_PARAM_VALUE2"  
               (And so on, for all other parameters your applet needs)
               pluginspage="http://java.sun.com/products/plugin/1.4/plugin-install.html">
                <NOEMBED>
                    No Java 2 SDK, Standard Edition v 1.4 support for APPLET!!
                </NOEMBED>
            </EMBED>
        </COMMENT>
    </OBJECT>
    </center>
    </body></html>
    Explanation:
    The title allows you to write some text that will appear in the title bar of the browser
    the green block of text is what Internet Explorer will use
    The blue block of text is what Netscape Navigator will use
    IE ignores the blue block because it thinks it is a comment
    Nav ignores the green block because it doesnt understand the OBJECT tag

    the jar name MUST be put twice into the EMBED tag, once because N_Nav uses the "java_archive" option and
    again because appletviewer uses the "archive" option

    Save and exit. Rename the file to MYAPP.html

    Double click this html file in Nav, IE, or pass it to the appletviewer (write a bat file containing appletviewer MYAPP.html instead of java -jar MYAPP.jar)

    You can also send the jar,and/or html/bat files to friends for them to run,easy as..just double click it!
    Last edited by cjard; July 30th, 2004 at 05:24 PM.
    "it's a fax from your dog, Mr Dansworth. It looks like your cat" - Gary Larson...DW1: Data Walkthroughs 1.1...DW2: Data Walkthroughs 2.0...DDS: The DataSet Designer Surface...ANO: ADO.NET2 Orientation...DAN: Deeper ADO.NET...DNU...PQ

  2. #2
    dlorde is offline Elite Member Power Poster
    Join Date
    Aug 1999
    Location
    UK
    Posts
    10,163
    Wow! nice one cjard

    One for the sticky FAQ thread...
    Please use &#91;CODE]...your code here...&#91;/CODE] tags when posting code. If you get an error, please post the full error message and stack trace, if present.

  3. #3

    Thumbs up

    I vote that this be added to the FAQ or stickied on it's own. Great job cjard!
    Note: I am a novice, take anything I say as coming from such.

  4. #4
    Join Date
    Dec 2003
    Location
    UK
    Posts
    113
    And I thank you from the bottom of my heart mate. Hope I will one day be able to pay this favour forward to someone else in distress.

  5. #5
    Join Date
    Jan 2004
    Posts
    30
    Rocking, think I will be using that

  6. #6
    Join Date
    Jan 2004
    Posts
    5
    Great post, thx cjard

  7. #7
    Join Date
    May 2003
    Posts
    38
    Thanks for the great post cjard, I have just started using Java Runner but that brings up a dos shell which is a bit annoying so I want to use your method.

    I am getting this error


    C:\FINAL>jar cvfm MYAPP.jar mf.txt -C APP APP\*
    java.io.IOException: invalid header field
    at java.util.jar.Attributes.read(Attributes.java:358)
    at java.util.jar.Manifest.read(Manifest.java:161)
    at java.util.jar.Manifest.<init>(Manifest.java:56)
    at sun.tools.jar.Main.run(Main.java:125)
    at sun.tools.jar.Main.main(Main.java:904)

    Having a clue what this means, have followed the instructions.

    Any help for this great idea would be super!

    OSR

  8. #8
    Join Date
    Oct 2003
    Location
    .NET2.0 / VS2005 Developer
    Posts
    7,104
    On the issue of the manifest; Manifest files are strange things. They must be made in an exact way, or they fail, possibly with the error you are experiencing. In the text below, the italic is the result you can expect. I've attached (a few posts later) some files demonstrating what i write here.
    The following rules describe a manifest, i will list only rules pertinent to the guide, though there are more

    manifest files must be text files
    there must be NO blank line at the start
    -failure: invalid manifest format - see mf_blankLineStart.txt
    the text within must start from the first column of the first line
    -failure: misplaced continuation line - see mf_untrimmedSpaces.txt
    the text must be of the form HEADER: VALUE
    -failure: invalid header field - see mf_malformedHeader.txt
    the header for the main class should be called Main-Class. later versions of jar are tolerant of main-class, MAIN-CLASS, MaIn-CLaSs etc, but early versions were not)
    -later versions correct it to Main-Class: MYAPP
    there must be a colon and a space between the value and the Main-Class text, like this: Main-Class: MYAPP
    -failure: invalid header field - see mf_malformedHeader.txt
    you must not use tabs between the header and the value
    -failure: invalid header format - see mf_tabs.txt
    there must be no trailing spaces at the end of the line
    - it will add the attribute, but the spaces will be present too. this may/not cause a problem
    the file to be used for a manifest should have at least blank line at the end
    -if you do not, the attribute will not be added to the manifest - see mf_noBlankLine.txt
    nothing must be present on the blank line (blank lines are kinda not-very-blank if they have something on them. like spaces. )

    -

    you will probably find that your manifest disobeys one of these. if not, post it and i'll have a play with it (use the attachment feature and attach your mf.txt)
    additionally, jar is so quirky, it might be somethign strange like you not saving the txt file in unix format.. like i say, if you do everything else, post it and i will have a look
    -


    another identified issue is:

    For some reason, my version of jar skips adding the first file in the first directory to the jar. I plan to write a program later to see if it is a bug in XP, or my version of jar.exe
    Last edited by cjard; January 14th, 2004 at 03:01 PM.
    "it's a fax from your dog, Mr Dansworth. It looks like your cat" - Gary Larson...DW1: Data Walkthroughs 1.1...DW2: Data Walkthroughs 2.0...DDS: The DataSet Designer Surface...ANO: ADO.NET2 Orientation...DAN: Deeper ADO.NET...DNU...PQ

  9. #9
    Join Date
    Oct 2003
    Location
    .NET2.0 / VS2005 Developer
    Posts
    7,104
    the bug appears to be with the JAR utility, i've even managed to crash it while i was testing. There was a relatively simple workaround, but it is definitely a nuisance. I'll decompile the jar utility later and see why it ignores the first file in some directories when the -C switch is used...

    for now, i have edited the guide as follows (quote=old version, followed by new version):


    Change directory to the FINAL folder
    -example, if your FINAL folder is on D: drive, in "javawork" folder then you type D:(return) followed by cd D:\javawork\FINAL(return))
    Change directory to the APP folder (inside FINAL folder)
    -example, if your FINAL folder is on D: drive, in "javawork" folder, then you type D:(return) followed by cd D:\javawork\FINAL\APP(return))

    Jar the files, using mf.txt as the manifest:
    -type jar cvfm MYAPP.jar mf.txt -C APP APP\*
    -substitute MYAPP for a nicer name. If your app was called DataViewer you might want to say: jar cvfm dv.jar mf.txt -C APP APP\*
    --explanation: cvfm makes your jar file of chosen name, using manifest named. the -C APP option mean "directory called APP is to be added"
    --the APP\* is expanded by dos, into a list of files in the APP directory. Be careful not to put the * on its own; it will cause some things to be put in the jar that are not necessary. Use APP\* only.
    Jar the files, using mf.txt as the manifest:
    -type jar cvfm ..\MYAPP.jar ..\mf.txt .
    -substitute MYAPP for a nicer name. If your app was called DataViewer you might want to say: jar cvfm ..\dv.jar ..\mf.txt *
    --explanation: cvfm= (c)reate jar (v)erbose output (f)ilename of jar [is specified] (m)anifest file [is specified]
    --the double periods, are expanded by DOS, to be the name of the parent directory, hence the jar file is placed alongside APP, not within it.
    --the final period(fullstop) . is expanded by DOS, into the path to the current directory. Jar understands this to be the base point


    Check that the jar file works:
    Check that the jar file works:
    -go to the parent directory, by typing cd .. (you should now be in the FINAL directory)



    The following text was added:
    One important issue here, is that JAR files are understood by java to be a filesystem of their own and like UNIX/LINUX, the filenames are case sensitive! Windows doesnt care for case sensitivity.
    This has implications, as you will see, because when you are putting your files in jar files, it is down to Java (not windows) to get them out!
    As a result, if your java program uses ANY external resources like icons, pictures, mp3, midi files, text files, xml files.. you MUST get the EXACT same name in the java source, as you do on the disk.
    Example: If your sourcecode looks like this:
    Code:
      ImageIcon ii = new ImageIcon("images/MyIcon.GIF");
    and your file is called "myicon.gif", then it WILL work before you put everything in the jar, but it WONT work after!
    Last edited by cjard; January 14th, 2004 at 01:53 PM.
    "it's a fax from your dog, Mr Dansworth. It looks like your cat" - Gary Larson...DW1: Data Walkthroughs 1.1...DW2: Data Walkthroughs 2.0...DDS: The DataSet Designer Surface...ANO: ADO.NET2 Orientation...DAN: Deeper ADO.NET...DNU...PQ

  10. #10
    Join Date
    Oct 2003
    Location
    .NET2.0 / VS2005 Developer
    Posts
    7,104
    the jar files i couldnt attach to an earlier post:
    Attached Files Attached Files
    "it's a fax from your dog, Mr Dansworth. It looks like your cat" - Gary Larson...DW1: Data Walkthroughs 1.1...DW2: Data Walkthroughs 2.0...DDS: The DataSet Designer Surface...ANO: ADO.NET2 Orientation...DAN: Deeper ADO.NET...DNU...PQ

  11. #11
    Join Date
    May 2003
    Posts
    38
    Im getting this error when I go to run my jar file

    C:\FINAL>java -jar MYAPP.jar
    Exception in thread "main" java.lang.NoClassDefFoundError: Calculator$1
    at Calculator.<init>(Calculator.java:97)
    at Calculator.main(Calculator.java:969)

    I will attached the Final folder, you will see that the main class is Calculator. The three different jar files are ones that I have changed the name of the app to see if it works. Even though I am using Calculator as my main class name in the mf.txt file it says it cant find it.
    Attached Files Attached Files

  12. #12
    Join Date
    Oct 2003
    Location
    .NET2.0 / VS2005 Developer
    Posts
    7,104
    Your jar file is suffering due to a bug in the jar command itself. I discussed it briefly, after I found that using jar's -C option would cause the first file in the main directory (APP) to be skipped.

    I worked with jar some more, and found a working syntax. If you printed the original topic, and are following the instructions, you need to reprint the topic, because I updated the guide last night, to include the new instructions.

    If, however, you ARE following the new instructions, please let me know. A comparison of the jar command in old and new, is shown below:

    Code:
    OLD: jar cvfm MYAPP.jar mf.txt -C APP APP\*
    NEW: jar cvfm ..\MYAPP.jar ..\mf.txt *
    the new command must be run from within the APP directory, the old command must be run from outside the APP directory (so you see, there have been a couple of significant changes to the guide.. check it out!)

    Even though I am using Calculator as my main class name in the mf.txt file it says it cant find it.
    If i can correct you there; java cannot find the class called Calculator$1. You have named the main class to be "Calculator" in your manifest, and that is working fine. However, because your main class Calculator has three inner classes, the java compiler has also generated the following files: Calculator$1, Calculator$2 and Calculator$3. All three of these are present in APP, but due to the bug in jar.exe, the first directory entry (Calculator$1) is being skipped. It is hence not available when java comes to run it, and this is what gives rise to the "Cannot find class Claculator$1" error message. Calculator and Calculator$1 are very different things!


    regards
    Last edited by cjard; January 15th, 2004 at 10:45 AM.
    "it's a fax from your dog, Mr Dansworth. It looks like your cat" - Gary Larson...DW1: Data Walkthroughs 1.1...DW2: Data Walkthroughs 2.0...DDS: The DataSet Designer Surface...ANO: ADO.NET2 Orientation...DAN: Deeper ADO.NET...DNU...PQ

  13. #13
    Join Date
    May 2003
    Posts
    38
    Thank you cjard, with the revised instructions it all worked fine. You are the man!

    I havent covered jar files yet in my studies, I believe they are in my next unit, so I really dont have the tech knowledge on how it all works just yet but Im learning.

    Thanks again!

  14. #14
    Join Date
    Jan 2004
    Posts
    30
    just pushing this up as its useful

  15. #15
    Join Date
    Oct 2003
    Location
    .NET2.0 / VS2005 Developer
    Posts
    7,104
    the tutorial has been updated, to include example html code for people wishing to pass parameters to their applets. I havent tested this, just colleted info from the web, so if anyone uses the html and finds an error in it, please let me know.

    an example usage may be:

    Code:
    
    <html><head><title>Animals applet!</title></head>
    <body><center>
    <OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
        width="800" height="650" align="baseline"
        codebase="http://java.sun.com/products/plugin/1.4/jinstall-14-win32.cab#Version=1,4,0,mn">
        <PARAM NAME="code" VALUE="AnimalInfo.class">
        <PARAM NAME="java_archive" VALUE="annymulls.jar">
        <PARAM NAME="type" VALUE="application/x-java-applet;jpi-version=1.4">
        <PARAM NAME="scriptable" VALUE="true"> 
        <PARAM NAME="animal" 
               VALUE="TIGER">
        <PARAM NAME="length" 
               VALUE="3 metres">
        <PARAM NAME="eats" 
               VALUE="people silly enough to go close">
    
        <COMMENT>
            <EMBED type="application/x-java-applet;jpi-version=1.4" width="800"
               height="650" align="baseline" 
               code="AnimalInfo.class" 
               archive="annymulls.jar" 
               java_archive="annymulls.jar"
               animal = "tiger"
               length = "3 metres"  
               eats = "people silly enough to go close"  
               pluginspage="http://java.sun.com/products/plugin/1.4/plugin-install.html">
                <NOEMBED>
                    No Java 2 SDK, Standard Edition v 1.4 support for APPLET!!
                </NOEMBED>
            </EMBED>
        </COMMENT>
    </OBJECT>
    </center>
    </body></html>
    "it's a fax from your dog, Mr Dansworth. It looks like your cat" - Gary Larson...DW1: Data Walkthroughs 1.1...DW2: Data Walkthroughs 2.0...DDS: The DataSet Designer Surface...ANO: ADO.NET2 Orientation...DAN: Deeper ADO.NET...DNU...PQ

Page 1 of 7 1234 ... LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)