I created a maven project, by convention we should put our packages in /src/main/java.
When I create a new package there, if I name it for instance "mypackage" , the package name will not take into account the namespace that I specified in the pom file, i.e "org.company.mypackage"
I end up having a class that looks like this :
package mypackage; // instead of org.company.mypackage
public class MyClass {
public void myMethod() {
...
}
}
The Maven "namespace" (the groupId) in the pom is not automatically prepended to Java packages. You have to do that manually (unless your IDE has some special functionality to do that for you)
Its a common convention to use the groupId and artifactId as base package of your project, but that is not enforced. If your pom contains
<groupId>org.company</groupId>
<artifactId>myproject</artifactId>
then all Java packages should start with org.company.myproject, e.g. org.company.myproject.mypackage.
Related
What do I want to do?
Given a POM file on the local filesystem.
I want to programmatically obtain the effective POM of that POM file. Specifically I want to do the following:
Resolve the POMs dependencies
Ensure that all parent POMs are processed
Obtain the list of dependencies of the fully resolved POM
And so on...
I don't need to obtain transitive dependencies.
What works?
I'm using Maven Resolver Provider which sort of works. However
I have to use a package private class org.apache.maven.repository.internal.DefaultModelResolver
Here a GitHub link to a sample Maven project that you can run: https://github.com/sahilm/maven-resolver-test
The example program does the following:
Downloads the latest spring boot POM from Maven Central.
Prints out it's direct dependencies (with parent deps included)
You can run the the program with:
mvn exec:java -Dexec.mainClass="com.sahilm.maven_resolver_test.Test"
What I need help with?
I need help with understanding why I have to use a package private class to get stuff to work.
Is there another way to get the information I need?
You can create (in your project) a public class under the package: org.apache.maven.repository.internal that extends the package-accessibility class. Just use a class name that is not possible to be used in the furutre by the vendor.
package org.apache.maven.repository.internal;
public class VisibleDefaultModelResolver extends DefaultModelResolver{
public VisibleDefaultModelResolver(RepositorySystemSession session, RequestTrace trace, String context, ArtifactResolver resolver, VersionRangeResolver versionRangeResolver, RemoteRepositoryManager remoteRepositoryManager, List<RemoteRepository> repositories) {
super(session, trace, context, resolver, versionRangeResolver, remoteRepositoryManager, repositories);
}
}
Then your code becomes:
ModelResolver modelResolver = new VisibleDefaultModelResolver(session, requestTrace, "context", artifactResolver, versionRangeResolver, remoteRepositoryManager, repos);
Maybe you can use ProjectModelResolver. Here's a code snippet,
DefaultRepositorySystem repositorySystem =
new DefaultRepositorySystem();
repositorySystem.initService(locator);
ModelResolver modelResolver =
new ProjectModelResolver(session, requestTrace,
repositorySystem, remoteRepositoryManager, repos,
ProjectBuildingRequest.RepositoryMerging.POM_DOMINANT,
null);
I've included a working code here.
How can I refer to a Java class in stdlib1.jar when the directory structure is like this? How to write the import statement?
I want to call a method under stdlib1.jar, I have configured it.
The classes are in the default package. According to this answer, it is not possible to import classes from the default package. So, they have to be moved to another package or you have to use reflection.
You call a method from a class and not from a package.
You don't need to specify the jar when you call a method from a class belonging to it. Which matters is your jar is in the classpath
In your screenshot if the lib makes part of the classpath folders, you can import and use classes from it in your code.
Here the classes of your jar use the default package (no package name) which seems weird for a third-party library. Default package is not recommended since it doesn't allow to naturally reference and use the classes of the archive from the client code.
I am not sure you are using the correct version of the jar. Look at that :
http://grepcode.com/snapshot/repo1.maven.org/maven2/com.googlecode.princeton-java-introduction/stdlib/1.0.1
This contains classes in the edu.princeton.cs package :
With package, you could declare this :
For example :
You could create a class like that and use BinaryIn like that:
package main;
import edu.princeton.cs.BinaryIn;
public class MyClass(){
public static void main(String args[]){
BinaryIn in = new BinaryIn();
}
}
I am writing some Java code without IDE, I got a little problem when I try run the code after compiling it. (I am using Ubuntu 64)
$ javac ClassName.java
$ java ClassName
Could not find or load main class ClassName
My directory structure is the following:
Projectname
----- PackageName
---------- className.java
---------- className.class
My code start by writing down the packageNmae. When I remove the package statement, it works. While error occur when that statement is included.
package PackageName;
public class myClass {
// .... to be used in the main class
}
public class ClassName {
public static void main(String args[]) {
// ....
}
}
Could anyone tell me what is the problem.
The main issue is where are you trying to run the command from. You do not run it from inside the package directory, but from the root of your package tree (in your example, the Projectname directory).
From there, you should be doing:
javac PackageName.className
which tells it to compile "className"[sic] inside package "PackageName"[sic]. The way you are doing it, you are telling it to compile a class that is not part of a package (which is strongly discouraged).
Notes:
Each file can only have a "general" class, with the name of that file.
You may define inner classes inside a class, but that would be inside the code block of the class.
package packageName;
public class ClassName {
public class InnerClass {
...
}
public static void main(String args[]) {
...
}
}
File name and class name must be the same. That includes case (lowercase or uppercase) of the name.
Class names always begin in uppercase.
Package names should be in camelCase.
Usually you do not want to leave your compiled (.class) files with the source (.java) files. The usual structure is, at the minimum:
--> Project --> src --> myPackage --> MyClass.java
--> bin --> myPackage --> MyClass.class
so you only need to copy your .class files to distribute the executable.
I'm using the org.reflections library to detect some classes that are annotated in my project. When I run the project from eclipse, the annotated classes are found.
However, when the project is packaged into a JAR file and run, no annotated classes are found.
Here is some example code:
#TestAnnotation
public class App {
public static void main (String[] args) {
Reflections reflections = new Reflections("com.package");
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(TestAnnotation.class);
for (Class c : annotated) {
System.out.println ("found annotated class " + c.getName());
}
}
}
When I run this code in a JAR file there is no output. What am I doing wrong?
Thanks
Pay attention to
Reflections reflections = new Reflections("com.package");
There you try to explore annotated classes located in package package which is nested in com package. But package is Java keyword. So it can not be used as name of package. After I moved App and TestAnnotation just into com package everything works fine.
But it is possible that your case is really bad. May be some tool or some person created package that has package name (for example, used Cyrillic а instead of Latin a, both are looking same in editor, but they are totally different for Java). When letters are mixed everything looks fine but doesn't work. So try to create new valid root package and move your classes into it.
My application allows developers to create some plugins. Сompliance with the requirements determined by base abstract class. Each plugin must have a name. I want to solve this problem by using annotations. So, I defined my own annotation Name as follows:
#Retention(RetentionPolicy.RUNTIME)
public #interface Name {
public String value();
}
I put this annotaion and base abstract class CommonPlugin into separate module and build it as JAR-file to share with developers.
Then I import package and put this annotation before the defenition of me test plugin as follows:
#Name("Test plugin")
public class TestPlugin extends CommonPlugin {
Then I reflect all given plugins through URLClassLoader and can't find necessary annotation at TestPlugin class. But if I define Name annotation into the same package the TestPlugin class is, I can find it. It should be so or am I doing something wrong?
Turning my coment into an answer so it can be accepted.
Make sure that the unqualified name Name refers to the same qualified name in all of your source files. In sources from different packages than the one containing the annotation, there should be a non-wildcard import for Name, and there should be no class with that name in that other package itself.