tags:

views:

231

answers:

5

I'm using maven to build the project and compile failed because I put class Test2 in Test.java,

but is it because of maven or simply because java itself doesn't support this?

BTW,how can I open a maven project with eclipse?

+3  A: 

Java requires you to have your public class inside a file with the same name.

For eclipse and maven use sonatype m2 plugin. Inside your maven project you can then type

mvn eclipse:eclipse

and maven will create a .project and a .classpath file for you. These are the files eclipse needs to work with the project.

You have to define the eclipse classpath variable M2_REPO with the path of your local maven repository.

With sonatype m2 you can do maven things from within eclipse: add dependencies, run maven targets, ...

tangens
The m2eclipse plugin has **nothing** to do with the maven-eclipse-plugin. If you use the former, you don't have to run `mvn eclipse:eclipse`. If you use the later, you don't have to use m2eclipse.
Pascal Thivent
Seems I can directly run `mvn eclipse:eclipse ` without installing sonatype me plugin?
httpinterpret
@pascal-thivent: Yes, you are totally right. I added m2 because it makes things easier in eclipse. But I missed to say that these are two distinct topics.
tangens
@httpinterpret: Yes, you can.
tangens
But I got an unbound classpath variable error in eclipse:`M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar`...And in `.project` there is a comment saying `NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse.`
httpinterpret
Inside eclipse you have to define a classpath variable `M2_REPO` that points to your local maven repository.
tangens
+5  A: 

A public class called ClassName must (in most cases) be defined in a file called ClassName.java.

Edit

Although this is not a requirement of the Java language, most (if not all) implementations of Java, the above mentioned relationship between the class name and file name must hold, or a compiler error will result.

(For more information, please refer to Jon Skeet's answer.)

The reason for this can be found by reading Section 7.2: Packages of The Java Language Specification, Third Edition.

In the section, it describes how the directory structure can be mapped to a fully-qualified class name in Java, which leads to a requirement that the .class file which contains the bytecode for a class must reside in a path that resembles that of the fully-qualified class name.

The original answer which incorrectly stated that the naming scheme is a requirement has been edited.

coobird
A: 

I'm using maven to build the project and compile failed because I put class Test2 in Test.java,

Source files must be named after the public class they contain, appending the suffix .java. In you case, the source file for the public class Test2 must be Test2.java 1.

is it because of maven or simply because java itself doesn't support this?

The Java compiler, javac, is complaining, not Maven (Maven doesn't change the behavior of the compiler).

how can I open a maven project with eclipse?

Either use the Maven Eclipse Plugin (i.e. a plugin for Maven) and simply run mvn eclipse:eclipse on your project and then Import... it as Existing Projects into Workspace in Eclipse. You will need to set a classpath variable M2_REPO pointing to the local repository to use it. Check the Usage page for the details.

Or (and that's an exclusive or) install m2eclipse (i.e. a plugin for Eclipse that extends it to make it able to understand a Maven projects and interact with it in a bi-directional way) and Import... your project as an Existing Maven Projects.

If EXCLUSIVE is not clear enough, this means: use one or the other but not both in the same time.

1 As mentioned by Jon Skeet, the JLS allows this restriction for file-based implementations. This doesn't apply when using a database to store Java constructs (like Visual Age for Java was doing). But in your case, it does.

Pascal Thivent
I don't think the m2eclipse will work because there is such a comment in the generated `.project`.
httpinterpret
`<comment>NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse.</comment>`
httpinterpret
@httpinterpret I explicitly wrote that they are EXCLUSIVE, you use one or the other, not both in the same time. I can't be clearer, just read carefully.
Pascal Thivent
@Pascal Thivent ,oops,you are right:) Finally,do you know where is the classpath variable `M2_REPO` restored? I don't see the definition in either `.project` or `.classpath`.
httpinterpret
@httpinterpret I don't know where it is physically stored exactly but it's available via Windows > Preferences > Java > Build Path > Classpath Variables.
Pascal Thivent
+4  A: 

The Java Language Specification itself doesn't actually require this - but it explicitly allows file-system-based implementations to do so, and most do.

From section 7.6:

When packages are stored in a file system (§7.2.1), the host system may choose to enforce the restriction that it is a compile-time error if a type is not found in a file under a name composed of the type name plus an extension (such as .java or .jav) if either of the following is true:

  • The type is referred to by code in other compilation units of the package in which the type is declared.
  • The type is declared public (and therefore is potentially accessible from code in other packages).

This restriction implies that there must be at most one such type per compilation unit. This restriction makes it easy for a compiler for the Java programming language or an implementation of the Java virtual machine to find a named class within a package; for example, the source code for a public type wet.sprocket.Toad would be found in a file Toad.java in the directory wet/sprocket, and the corresponding object code would be found in the file Toad.class in the same directory.

When packages are stored in a database (§7.2.2), the host system must not impose such restrictions. In practice, many programmers choose to put each class or interface type in its own compilation unit, whether or not it is public or is referred to by code in other compilation units.

For practical purposes I think it's reasonable to basically assume that it's required.

Jon Skeet
A: 

The connection between file name and class name is the following:

  • if you have public class in a file, the filename must be the same as the class name
  • you can have as many non-public classes as you want in a file with different names
Leni Kirilov