-1

Two questions

1) When exporting a java project as a JAR file, how does the application know which Class in the package to run first? My applicatino specifically requires that the userInterface.java file run before the CommonDenom.java file.

2) When running the java file I'm getting an error that says "The Java JAR file "commonDenom.jar" could not be launched. Check the Console for possible messages."

Where do I start to figure this out? I checked the console but it doesn't seem to be registering anything at the time the error message pops.

package commonDenom;

import java.util.Arrays;
import java.util.Scanner;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;


public class UserInterface {
    Shell shell;
    Button btnNext;
    Button btnDone;
    Text input;
    Text output;
    static int count;
    static int[] finalNums;
    int[] nums = new int[1000];

    public static void main(String[] args){
        Display display = new Display();
        new UserInterface(display);
        display.dispose();
    }

    public UserInterface(Display display){
        shell = new Shell(display);
        shell.setSize(220,350);
        shell.open();

        input = new Text(shell, SWT.SINGLE);
        input.setBounds(10, 10, 100, 20);

        btnNext = new Button(shell, SWT.PUSH);
        btnNext.setBounds(10, 40, 100, 30);
        btnNext.setText("Next");
        nextPress();

        btnDone = new Button(shell, SWT.PUSH);
        btnDone.setBounds(10, 80, 100, 30);
        btnDone.setText("Done");
        donePress();

        output = new Text(shell, SWT.SINGLE);
        output.setBounds(10, 120, 200, 200);

        while(!shell.isDisposed()){
            if(!display.readAndDispatch()){
                display.sleep();
            }
        }
    }

    public void nextPress(){

        btnNext.addSelectionListener(new SelectionAdapter(){
            int x = 0;
            @Override
            public void widgetSelected(SelectionEvent e) {
                    nums[x] = Integer.parseInt(input.getText());
                    System.out.println("nums[" + x + "]:" + nums[x]);
                    x++;
                    count++;
            }
        });
    }

    public void donePress(){
        btnDone.addSelectionListener(new SelectionAdapter(){
            @Override
            public void widgetSelected(SelectionEvent e) {
                finalNums = new int[count]; 
                for(int i = 0; i < count; i++){
                    finalNums[i] = nums[i];
                }
                System.out.println("finalNums:" + Arrays.toString(finalNums));
                commonDenom.compare();
                if(commonDenom.getResult() == 0){
                    output.setText(Arrays.toString(finalNums) + "\nThese numbers do not have a \ncommon multiplier");
                }
                else{
                    output.setText(Arrays.toString(finalNums) + "\nResult:" + String.valueOf(commonDenom.getResult()));
                }
            }
        });
    }
    public static int[] getNums(){
        return finalNums;
    }
}

Manifest.txt location: /Dropbox/workspace/commonDenom/bin

Class location: /Dropbox/workspace/commonDenom/bin/commonDenom/

Class names:

commonDenom.class
UserInterface.class
UserInterface$1.class (I didn't create this)
UserInterface$2.class (I didn't create this)

Manifest.txt content (with two trailing blank lines):

Main-Class: commonDenom.UserInterface

jar tf CommonDenom.jar returns the following:

META-INF/
META-INF/MANIFEST.MF
Manifest.txt
commonDenom/
commonDenom/commonDenom.class
commonDenom/UserInterface$1.class
commonDenom/UserInterface$2.class
commonDenom/UserInterface.class
dbconfession
  • 1,147
  • 2
  • 23
  • 36
  • What do you meant by _My applicatino (sic) specifically requires that the userInterface.java file run before the CommonDenom.java_? Only **one** class is run - the one specified as the `Main-Class` in your `META-INF/MANIFEST.MF`. See [this](http://docs.oracle.com/javase/tutorial/deployment/jar/appman.html) for more information. P.S. you post of **riddled** with typos. This shows little to no effort on your part. Why should we put effort in if you cannot be bothered? – Boris the Spider Mar 05 '14 at 23:11

2 Answers2

2

I recommend to create the jar by hand first. It will be a good sanity test, and you will learn what it takes to do it. Here are the steps:

  1. Create a Manifest.txt file somewhere, let's say your project root. One line is enough, like this:

    Main-Class: commonDenom.UserInterface
    

    Make sure the file ends with a newline. Eclipse doesn't put a newline at the end of the file by default. It's ok to have trailing blank lines.

  2. Go to the parent directory where Eclipse puts your class files. For example in a Maven project this is target/classes relative from the project root. Ant builds might use bin instead. In your example this should be the directory that contains commonDenom (which in turn contains the build product: UserInterface.class)

  3. Create the jar:

    jar cfm /tmp/somename.jar /path/to/Manifest.txt commonDenom
    # or probably:
    jar cfm /tmp/somename.jar /path/to/Manifest.txt *
    

    This will put your tree of class files into the jar with the specified manifest file.

Now you should be able to run this file. This can be your baseline test.

You can check the content of the jar with the command:

jar tf /tmp/somename.jar

It should print something like:

META-INF/
META-INF/MANIFEST.MF
commonDenom/UserInterface.class
...  # your other class files...

Now that you have your baseline test, you can try to create the jar using Eclipse. If the jar created by Eclipse doesn't work, you can look at its content to see the differences from your baseline case, which should help you debug the problem.

janos
  • 120,954
  • 29
  • 226
  • 236
  • 1
    I agree - please build the jar by hand as I suggested earlier and tell us what happens. – jgitter Mar 06 '14 at 13:20
  • In the process of making the jar now. I put the Manifest.txt in CommonDenom (the same dir that has bin and src). Then you say to navigate (I'm assuming in terminal) to the folder that has the root project commonDenom, which is bin. (note that The project is named 'commonDenom' and the package is also called 'commonDenom.') So now in terminal my path reads 'Stuart-Kuredjians-iMac-2: bin skuredjian$' Since 'Manifest.txt' is on the same level as 'bin' and I'm already in 'bin,' how do I back up one level when designating the /path/to? – dbconfession Mar 07 '14 at 23:01
  • btw.. i moved the manifest INTO bin and it worked. But what if I wanted the manifest to stay at the same level as bin instead of in it? I don't know how to designate the level above the one I'm in. – dbconfession Mar 07 '14 at 23:10
  • also where exactly is this/tmp/ folder. Obviously it created the .jar because I can see the contents. But where is the actual jar file? I'ts not coming up in spotlight – dbconfession Mar 07 '14 at 23:14
  • I replaced /tmp/"Common Denominator.jar" with just "Common Denominator.jar" and it created the file. But when I try to launch it, I'm still getting the same error "The Java JAR file 'Common Denominator.jar' could not be launched. Check the console for possible error messages." – dbconfession Mar 07 '14 at 23:18
  • I should mention are that the workspace is on my dropbox. But that shouldn't matter because theres a local version anyway. I'm not sure what other variable I could be missing that is not allowing this to run. I'm using the 64 bit SWT so that shouldn't be a conflict. Unless it matters that I started writing the code with the 32 bit, deleted the the 32 bit and imported the 64 bit. Other than that I'm at a loss. – dbconfession Mar 07 '14 at 23:21
  • I just noticed that the manifest order shows 'commonDenom/commonDenom.class' , 'commonDenom/UserInterface$1.class' , 'commonDenom/UserInterface$2.class' and 'commonDenom/UserInterface.class' So i think that because it's on dropbox, there's constantly a temp file for the classes while it is syncing and the manifest is pulling those in. Regardless, however, isn't the first class supposed to be the entry point? And if so, why does mine list commonDenom.class as the first? – dbconfession Mar 07 '14 at 23:26
  • @StuartKuredjian No, the first class isn't supposed to be the main-class. Please post the actual error message you get when running the jar file via 'java -jar'. Not via Eclipse, it's of no interest. Eclipse won't be there in production. – user207421 Mar 08 '14 at 02:09
  • @EJP java -jar CommonMult.jar returns "no main manifest attribute, in CommonDenom.jar" – dbconfession Mar 08 '14 at 02:49
  • I've updated the original post to include class names.locations and Manifest information. How come there are different UserInterface classes? The original UserInterface.class as well as UserInterface$1.class? and UserInterface$2.class? – dbconfession Mar 08 '14 at 03:04
  • The `UserInterface$1.class` is an inner class, created inside `UserInterface`. It's probably the anonymous `SelectionAdapter` created in the `nextPress` method. This is perfectly normal, nothing fishy there. From your update it seems you didn't use the `m` flag when you created the jar. For example, as if instead of `jar cfm ...` you did `jar cf ...`. If the `m` flag is there correctly, the manifest file will become part of `META-INF/MANIFEST.MF`, and `Manifest.txt` won't be in the list when you do `jar tf`. And your jar will work :) – janos Mar 08 '14 at 07:12
  • @Janos If I understand correctly, you're saying that the reason the jar won't run is because instead of using 'jar cfm CommonDenom.jar Manifest.txt *', I used 'jar cf CommonDenom.jar Manifest.txt *' I assure you that is not the case. To confirm I just tried it again and made sure I created with cfm (not cf). Perhaps it has to do with where Manifet.txt and the jar file are in relation to each other. Both are on the same level inside the bin folder. – dbconfession Mar 08 '14 at 16:31
  • @StuartKuredjian yes that's what I meant. It shouldn't matter where the files are. If I create a jar file with `cf`, then `Manifest.txt` will be in the jar as in your output, and the jar will NOT be executable. If I create it with `cfm` then it will not be in the jar with its original name, but incorporated into `META-INF/MANIFEST.MF` and the jar works. If `jar tf` shows you `Manifest.txt` that's not a good sign. – janos Mar 08 '14 at 16:36
  • @Janos also. I tried compiling the java files in terminal instead of using the .class files that Eclipse makes and it returns errors which seem to be associated with the SWT library. For example, 'UserInterface.java:61: error: cannot find symbol btnNext.addSelectionLitener(new SelectionAdapter(){ su,bol: class SelectionAdapter location: class UserInterface 26 errors' There's a carrot under the 'S' in SelectionAdapter. I just realized that in compiling this, the SWT library isn't included anywhere. Maybe that's the problem? – dbconfession Mar 08 '14 at 16:45
  • @StuartKuredjian It's totally ok to use the class files built by Eclipse, no need to build yourself. I triple-checked, and I really cannot create a broken jar like yours, where `Manifest.txt` is listed in the jar as a regular file, without properly integrated into `META-INF/MANIFEST.MF`. – janos Mar 08 '14 at 17:02
  • @Janos thanks for trying. Could I message or email you and just walk you through what I'm doing as you do it, so I know for sure I'm not skipping any beats? – dbconfession Mar 08 '14 at 17:11
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/49313/discussion-between-janos-and-stuart-kuredjian) – janos Mar 08 '14 at 17:13
  • @Janos thanks for your help. If you're interested, I've posted the newst problem here: http://stackoverflow.com/questions/22273960/swt-exception-when-running-jar-exception-in-thread-main-org-eclipse-swt-swtex – dbconfession Mar 08 '14 at 19:33
1

You can define an entry point of your application in the MANIFEST file. Have a look here: http://docs.oracle.com/javase/tutorial/deployment/jar/appman.html

Jakub H
  • 2,130
  • 9
  • 16
  • Thanks. I read the document and this is the first I'm hearing of the manifest. Where is this? Is it a file? Can the entry point be designated in eclipse before packaging the jar file? Or i have to edit an actual text file? Thanks. – dbconfession Mar 05 '14 at 23:20
  • Never mind I found it in the Export Wizard. Let me try this and see if it works. By default, f I don't specify, which class does the packaging tool designate as the entry point? – dbconfession Mar 05 '14 at 23:22
  • It's not working. I designated the correct entry point class, but I'm still getting the "The Java JAR file "commonDenom.jar" could not be launched. – dbconfession Mar 05 '14 at 23:24
  • How are you running it? Can you run it in a console and paste the output? java -jar commonDenom.jar – jgitter Mar 05 '14 at 23:26
  • running java -jar CommonDenom.jar com.app.Test returns Error: Unable to access jarfile commonDenom.jar – dbconfession Mar 05 '14 at 23:30
  • It sounds to me like the jar is corrupted. How exactly are you building it? Have you tried building it by hand? Check out http://docs.oracle.com/javase/6/docs/technotes/tools/windows/javac.html and http://docs.oracle.com/javase/tutorial/deployment/jar/build.html – jgitter Mar 05 '14 at 23:34
  • I've edited the original post to include the code of the file that is being designated as the entry point by the manifest. Just in case it has something to do with the code. – dbconfession Mar 05 '14 at 23:46
  • @jgitter I'm clicking File >> Export >> Java >> JAR File >> Next. Then checking the box for the project commonDenom (not sure if I'm also supposed to include the project for the SWT library, but when i do it doesn't work anyway). I leave "Export generated class files and resources" checked. Export Destination is my desktop. For Options I have "Compress the contents of the JAR file" selected. On the third page I select UserInterface (above) as the entry point class. Then I click finish. – dbconfession Mar 05 '14 at 23:50