There are numerous examples showing how to get the package name in code at runtime.
In my case, I need to test the package name at compile time.
Here is my situation: I have two Android projects (the free and the pro) which leverage a library project.
The free version has a "Get the pro version" menu item, which does not exist in the other version.
My menu handling code goes like this:
if ( item.getItemId()==R.id.getProVersion ) {
//...
}
Proguard complains that R.id.getProversion does not exist when building the pro package.
So I need to test which project is being built, to exclude this part of the code from being compiled.
Is there a way to know the package name at compile time ?
Are there alterative solutions to this problem ? Either Android-centered or java-centered solutions are fine.
You can put the menu item in the library project, and then use the runtime package name checks to actually decide whether to display the message or not
You could do that by writing a simple annotation that automatically skips this peace of code. Myabe it's overkill, but it's also a good way to get into preprocessing...
This seems to be a good (KISS) tutorial on the topic:
http://blog.christoffer.me/2011/08/how-to-enforce-static-methods-on-class.html
Related
I'm a n00b coder. I found an interesting library and trying to start toying with it. Which is not going great. This library is from 99' and uses JUnit (which I'm unfamiliar with) so there is a lot of confusing stuff. But it seems like the source of my failing even more elementary. Namely I have troubles importing packages.
This library has a test called StandardEvalTest.java. I moved to it to main Java directory and now I'm trying and failing to launch it using JUnit.
This package path org.pokersource.game.Deck goes directly from the directory where the test StandardEvalTest.java sits.
I also added the main java directory to the PATH environmental variable. Which as I assumed will allow import to locate the package.
None of those two things help. Also I was suspecting that maybe Deck.java and Deck.class are not enough and I have to do some work to create a package from it. But as far as I can say from Oracle doc the only thing needed is a package name in the header. Which seems to be present.
So I'm out of moves. Please help!
PS: Some additional info inspired by #Dhrubo 's answer:
The test I'm trying to run indeed sits in the main java folder of the library. (I moved it here hoping that when running from here it would be easier to find the package)
If I'm trying to compile the test instead of running it with JUnit he seem to fail to find JUnit classes and other JUnit related stuff.
[Oh OK I'm an idiot! Dont't mind me]
You should include the package while running StandardEvalTest.java as below
javac -cp [classpath] org.pokersource.game.StandardEvalTest.java
and run it from package root directory, I am assuming it is custom java file that you want to compile. You run directory should be parent of your package directory.
** I also see, you are trying to compile StandardEvalTest.java instead of Deck.java ... then check your StandardEvalTest.java file whether it exists in desired location.
I am learning Java on Visual Studio Code. I have installed the "Microsoft extension for Java" in it. My basic Java programs runs fine without package declaration. But I would like to package my program. How ?
Earlier I used "IntelliJ IDEA". I used to start a New Project and declare "package com.java.learn". In Visual Studio Code there is no option to create New java Project. There is an option to create Workspace but I still have the same issue.
I have two java class. "Index.java" & "InputHelper.java". Index.java is the main java file. InputHelper is a seperate class which I use in Index.java. I want to make a project and package both ( or more ) files.
Error Message:
The declared package "com.java.learn" does not match the expected package
A package is a path of subdirectories. Say your java sources are in (subdirectory of) a directory src. All sources immediately under src have the "default" package = no package declaration.
In src/com/java/learn (4 nested directories) the package com.java.learn; is expected for java sources.
In your case create a path of 3 directories: com, java, and learn the latter containing your java source.
For the rest, try to follow the coding conventions of java: class names starting with a capital like Index, variable and method names with a small letter.
In fact though Microsoft is often underestimated, I would chose a more mainstream IDE for learning java. IntelliJ IDEA (Community edition) is fine; NetBeans IDE is a clean an nice IDE too; eclipse is used very often - though a bit overdone IMHO.
I faced a similar issue, coming from Eclipse/IDEA background you find it difficult to not have a feature in your java IDE to create a new package.
Although, Joop Eggen's answer is correct that package is a path of subdirectories but you might find it tedious to create subdirectories when the number of sub packages is greater and name of sub packages is long.
You can use the below VSCode extension :
https://github.com/jiangdequan/vscode-java-saber
It is a very handy extension.It provides support for:
New: Java files(annotation/class/interface/enum/package/JSP/HTML)
Generate Getters and Getters
Copy Qualified Name
Sort Project By Name
Run Maven Goals
Generate Docs
You can try this extension.
You can use Java Projects panel to create a new project, package, class.
Also I think there's an issue in VSC 1.63.2, because a new item is created but it's not displayed in project structure until I reload VSC window.
Another option is to put right package declaration on the first line of a class file and use inline 💡light bulb button to move that class to the package it belongs.
P. S. I'm learning Java now so I could be missing something
I've been using Eclipse for a while and I'm having trouble understanding what's going on with my first project in IntelliJ. I've read the documentation, and searched other questions, but I still can't seem to grasp it. I think there is something wrong with my project structure. This is what my structure currently looks like;
I'm trying to run the JavaForLoop class, but whenever I do, compilation fails because I have errors in the StringMethods class of the strings package. My question is why would that prevent compilation if the two classes are in separate packages? Neither class uses the other, and they both have the appropriate package declaration statements. With a similar structure in Eclipse, this would work. Should I be using a different project structure?
By default IDEA adds Build Configuration which is executed before launch and includes following steps (taken from here):
Compiling source code in the source path of a module and placing results to the output path.
Compiling source code in the test path of a module and placing results to the test output path.
Creating copies of the resource files in the output path.
Reporting problems in the Messages tool window.
check if it's your case in Edit Configuration screen and if so, remove it.
To use a class from a different package you must declare a import statement to the class.
In your JavaForLoop.java add the import before the class statement (and after package declaration where its the case)
//package ...
import strings.StringMethods;
//public class JavaForLoop { and the rest of the code
Intellij uses regular javac, which will fail to compile if you have errors anywhere in the code.
Eclipse has it's own compiler, that allows to compile and even run code that has compilation errors, causing a runtime exception if any part of the code that has errors is run. This allows you to run parts of the code that work even if other pieces of code are failing.
The simple solution is to resolve your compilation errors. You can also use the eclipse compiler with Intellij, but I've never done this so I can't comment on how well it works.
I've recently discovered Error Prone and am integrating it into my Android build using the Gradle plugin linked on their page.
Since our project is using Icepick (and some other code generating annotation processors), we have generated source code, which gets compiled in. Unfortunately, some of the generated code triggers warnings in Error Prone, and I'd like to filter that noise out somehow.
The generated code shows up in the app/build/generated/source/apt/debug directory. How can I exempt this code from Error Prone's steely gaze?
Use the flag -XepDisableWarningsInGeneratedCode
See this issue on GitHub
In my case classes were annotated with #AvroGenerated and -XepDisableWarningsInGeneratedCode didn't work.
The solution was to exclude build directory from checks via -XepExcludedPaths:.*/build/.*
We have a package that ends with exception e.g.
package a.b.c.exception;
Our code base had no issues up till eclipse 3.3, however when we shifted to eclipse 3.4, it started giving errors related to this package:
"The package a.b.c.exception collides with a type"
When I refactor the package name to a.b.c.exceptions, there are no issues. Is this due to a bug in eclipse 3.4 or is there some setting to rectify this behavior?
It's because you have a class named exception (with a lower case "e") in the a.b.c package and a package named a.b.c.exception.
It causes a name collision because if you have the code a.b.c.exception.doSomething(); - does that mean you want to call the static doSomething() method in the a.b.c.exception class? Or does it mean there's a class called a.b.c.exception.doSomething that you're trying to invoke the constructor of?
Stick with the Java naming conventions - packages all lowercase, classes starting with an uppercase and camel-case after - and you'll never see this problem.
==========EDIT==========
This is the only legitimate reason this error should be showing up...
It doesn't have to be in your project directly, it could be in another project or library that your project depends on. This should show you any occurrences of the class anywhere on the build path or your project : Hit the Flashlight looking button in the Eclipse toolbar -> Choose 'Java Search' -> enter a.b.c.exception in search field -> select 'Case sensitive' -> select 'Type' in 'Search For' -> make sure all options are selected for 'Search In'.
Are you using any tools that generate classes? Could they be putting them into the build directory of your project? When you see the error, if you go to the project's build directory, and go down into the a/b/c/ directory do you see a .class file for 'exception'?
Of course Eclipse in general could have a bug (though I'd expect there would be a bug report in Eclipse 3.4 and you'd be able to find more complaints if it was...), your Eclipse install could be broken in some way (Can anyone else open your project in Eclipse 3.4? Could you do a clean Eclipse 3.4 install in another directory? Does the error appear there?), or your project could be messed up in some way (Create a new project with no dependencies other than the JDK, create the a.b.c.exception package in your new project, create a class in your project to import a.b.c.exception.*; and see if the error occurs.).
In Java you can not have a class name that is the same as a package name.
That means the JDT package must have enforced that rule only in 3.4
See bug 63668 for instance.
As Nate comments:
A class named Exception won't prevent you from creating package exception.
Case matters.
Also remember the full name of a class includes the package it's in.
So a.b.SomeClass (class name) is different from x.y.SomeClass (package name).
There would be no name collision here.
The class name and the package name have to match in both case and package to cause this error.
See his more accurate answer.
I encountered a similar problem in a huge code base that I inherited. It turns out that the clash was caused by an partially qualified class name in a JavaDoc link.
To paraphrase, Eclipse was telling me that I had a package/type clash for a.b.c.d. when compiling a.b.c.d.London. Doing a java search on the code for a.b.c.d revealed that Eclipse thought that a JavaDoc comment in a.b.c.Paris was a match. The JavaDoc comment contained {# link d.NewYork}. When I changed the it to read {#link a.b.c.d.NewYork} the compilation error was resolved.
It should also be noted that NewYork was not imported into the Paris class as it only appeared in the JavaDoc comment. This also made it un-resolved in its abbreviated form and clicking on the link in the comment did not work. Making it an absolute reference also makes the JavaDoc link work.
I know this will sound silly, and possibly too simple to be true, but I solved this exact same error message by:
Deleting the entire line of the package name causing the error message.
Saving the .java file(this triggers a new error on the same line stating "The declared package "" does not match the expected package"), which it should do.
Re-typing the original package name onto the same line.
Saving the .java file.
Could not tell you why this worked, but it did, and Eclipse stopped throwing a tantrum on the spot.
Safe typing and speedy coding.
-Goodge
I changed one of the compilation option in eclipse and the problem disappeared.
Under workspace properties:
Java Compiler -> Errors/Warnings ->
Change 'Unused import' from 'Warning' to 'Ignore'.
If you have a class Foo, you cannot have a package that ends with Foo, such as com.my.Foo.
Also if you are using maven style, you have resources in your project under something like src/main/resources
The folders in your resources also have a package style and there, also, you cannot have a folder that contains the name of your class.
you will definitely encounter this problem when developing a Jenkins plugin according to the recommended conventions.
if you follow the Jenkins conventions, and you create a builder in a class named MyBuilder in package x.y then you are also supposed to place your .jelly in a resource folder named x.y.MyBuilder. This will result in the above problem.
However, if you name your resource folder x.y.myBuilder (notice lower case 'm' in myBuilder), unlike the recommended convention, the plugin will still work as you intended