Reputation: 7653
Below is my project directory. I am trying use Kitchen.jar (located in libs folder) as a file dependency.
Below is my build.gradle file where I attempt to include Kitchen.jar as a dependency.
plugins {
// Apply the java plugin to add support for Java
id 'java'
// Apply the application plugin to add support for building a CLI application
id 'application'
}
repositories {
// Use jcenter for resolving dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
}
dependencies {
// This dependency is used by the application.
implementation 'com.google.guava:guava:27.1-jre'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
compile files('libs/Kitchen.jar')
}
application {
// Define the main class for the application
mainClassName = 'Kitchen.App'
}
However, when I run gradle build
I get a compiler error, which tells me that the Kitchen.jar file has not been imported correctly. "Food" is a class in Kitchen.jar.
This is what the Oven class looks like for some context on what insertFood
method looks like.
package Kitchen;
/**
* This class models an oven appliance for cooking food.
*/
public class Oven {
private final int maxTemperature;
private int currentTemperature = 0;
/**
* Creates an Oven object with a default maximum temperature of 320 degrees Celsius
*/
public Oven() {
this(320);
}
/**
* Creates an Oven object with a specific maximum temperature
*
* @param maxTemperature The maximum temperature this oven can be set to. Cannot be a negative number.
* @throws IllegalArgumentException If the maxTemperature is negative
*/
public Oven(int maxTemperature) {
if (maxTemperature < 0) {
throw new IllegalArgumentException("Invalid temperature");
}
this.maxTemperature = maxTemperature;
}
/**
* Sets the current temperature of the oven to the given value
*
* @param temperature The temperature to set in degrees Celsius
* @throws IllegalArgumentException If the temperature is negative or higher than this oven's maximum temperature.
*/
public void setTemperature(int temperature) {
if (temperature < 0 || temperature > maxTemperature) {
throw new IllegalArgumentException("Invalid temperature");
}
this.currentTemperature = temperature;
}
/**
* Gets the current temperature (the oven has no heating or cooling times and changes temperatures instantly)
* @return The current temperature in degrees Fahrenheit
*/
public int getCurrentTemperature() {
return (currentTemperature * 9/5) + 32;
}
/**
* Gets the maximum temperature this oven can be set to
* @return The max temperature in degrees Celsius
*/
public int getMaxTemperature() {
return maxTemperature;
}
/**
* Adds an item of food to the oven, potentially changing its state.
*
* @param food The food to be added to the oven
* @param duration The length of time in minutes the food will be in the oven for
* @throws IllegalArgumentException If the food parameter is null, or if the duration is negative
*/
public void insertFood(Food food, int duration) {
if (null == food) {
throw new IllegalArgumentException("Food may not be null");
}
if (duration < 0) {
throw new IllegalArgumentException("Duration must be >= 0");
}
food.cook(currentTemperature, duration);
}
}
Similarly, IDEA shows a similar error as shown below.
I've tried manually adding the Kitchen.jar file as a dependency via the "Project Structure" window (see below) and even though it is added as a dependency according to the screenshot, the above errors persist.
I've also tried File -> Invalidating Caches / Restart; however, this doesn't resolve my issue.
Why is it that none of the classes in my Kitchen.jar file such as "Food" are registered in my Gradle project?
Edit 1:
I've attempted 0xadecimal's solution as shown below but unfortunately it still fails to compile and Intellij throws the same error about not resolving symbol "Food" in the Oven class as shown below.
Edit 2:
I've attempted Lukas Körfer's suggestion in the comments to use implementation files(...)
; however, I'm still getting the compile error and Intellij is still yelling at me (right hand side of the screenshot). Note that every time I change the build.gradle file I make sure I run dependencies by hitting the green button next to dependencies
even though I've set up my Intellij to auto update when the build.gradle
file changes. This means the problem shouldn't be because the dependencies are not updating in Intellij.
Upvotes: 2
Views: 2839
Reputation: 726
I think the issue is that you are trying to import a class from an unnamed package (any of the classes within the Kitchen.jar
) from a class within a named package (Kitchen.App
).
Java does not allow the importing of classes from the default (unnamed) package into named packages - this is what is causing the compile time error you are seeing:
From the Java Language Specification 7.5.1
The type must be either a member of a named package, or a member of a type whose outermost lexically enclosing type declaration (§8.1.3) is a member of a named package, or a compile-time error occurs.
To fix this issue you can either:
Ensure that the code shipped in the Kitchen.jar belongs to a named package. If the JAR only contains compiled class files and you don't have access to the source code then this isn't an option. If you do have access to the source code and can rebuild this JAR, then you need to put in place a package structure so that the classes are not all sitting in the root of the JAR, e.g:
home/util/AbstractFood.java
home/util/Food.java
home/util/Fries.java
home/util/Kitchen.java
home/util/Oven.java
home/util/Potato.java
with package home.util;
at the top of each of the files.
You should then rebuild the jar and import the classes in your App.java
and Oven.java
using import home.util.Kitchen;
, import home.util.Oven;
,etc.
Kitchen
) into the default (unnamed) package. This is not a good idea - we should not be writing code in the default package, but if you can't execute option 1, this is your only option. What this means is moving your java code (App.java, Oven.java
) to reside directly in the src/main/java
directory, and also removing any package Kitchen
declaration from the top of these files. You will also need to set mainClassName = 'App'
Upvotes: 2