Having JAVA_HOME inconsistency issue with maven - java

I am on the verge of releasing a project but it seem JAVA_HOME is been inconsistent. Maybe it's been overridden somewhere else? I am using ubuntu 14.04 and I have openjdk-7, java-7-oracle, java-8-oracle. Default java was set using update-java-alternatives
java -version
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
mvn -version gives the following output
Apache Maven 3.2.1 (ea8b2b07643dbb1b84b6d16e1f08391b666bc1e9; 2014-02-14T17:37:52+00:00)
Maven home: /usr/share/maven3
Java version: 1.8.0_25, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-8-oracle/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.13.0-39-generic", arch: "amd64", family: "unix"
But when doing mvn release:prepare, below is what I see:
[INFO] Not generating release POMs
[INFO] Executing goals 'clean verify'...
[WARNING] Maven will be executed in interactive mode, but no input stream has been configured for this MavenInvoker instance.
[INFO] Error: JAVA_HOME is not defined correctly.
[INFO] We cannot execute /usr/lib/jvm/java-8-oracle/bin/java/bin/java
It looks like the java executor is being looked for in the wrong folder : /java/bin/java. I have tried changing java home to /usr/lib/jvm/java-8-orable/bin but it broke mvn-version check.
How to fix this? Thanks for reading
I can't find here to fix that. Has anyone encountered anything similar?
EDIT 1:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
<configuration>
<excludes>
<exclude>**/*ITest.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>${project.build.sourceEncoding}</encoding>
<meminitial>128m</meminitial>
<maxmem>512m</maxmem>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<preparationGoals>clean verify</preparationGoals>
<tagBase>https://xxxx/svn/projectname/tags</tagBase>
</configuration>
</plugin>
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>maven-apt-plugin</artifactId>
<version>1.0</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.9</version>
</plugin>
</plugins>
</pluginManagement>
</build>
I have switched to java-7-oracle and still no chance:
[INFO] Executing goals 'clean verify'...
[WARNING] Maven will be executed in interactive mode, but no input stream has been configured for this MavenInvoker instance.
[INFO] Error: JAVA_HOME is not defined correctly.
[INFO] We cannot execute /usr/lib/jvm/java-7-oracle/bin/java/bin/java
EDIT 2:
Dear down voters, I am not asking for help about how to set Java Home. It's been set to
/usr/lib/jvm/java-8-oracle
Then to the following when I tried running same thing with java 7
/usr/lib/jvm/java-7-oracle
This is set in /etc/profile.d/jdk.sh by webup8 script
export J2SDKDIR=/usr/lib/jvm/java-7-oracle
export J2REDIR=/usr/lib/jvm/java-7-oracle/jre
export PATH=$PATH:/usr/lib/jvm/java-7-oracle/bin:/usr/lib/jvm/java-7-oracle/db/bin:/usr/lib/jvm/java-7-oracle/jre/bin
export JAVA_HOME=/usr/lib/jvm/java-7-oracle
export DERBY_HOME=/usr/lib/jvm/java-7-oracle/db
EDIT 3
I have switched to openjdk 7 , edited the jdk.sh to reflect this export JAVA_HOME=/usr/lib/jvm/java-1.7.0-openjdk-amd64 and the error went. I run to other famous issues (permission issues to tags folder. weird) . So it's not related to the maven itself I guess. But this is weird that it works fine for openjdk ...

JAVA_HOME must point to jre, not jdk. Then set :
export JAVA_HOME=/usr/lib/jvm/java-8-oracle/jre

Creating a file .mavenrc on my home folder and adding the code below solved the problem for me. (Ubuntu 14.10, Maven 3.2.1)
export JAVA_HOME=/usr/lib/jvm/java-8-oracle

Another workaround:
export JAVACMD=$JAVA_HOME/bin/java
setting /usr/lib/jvm/java ⇒ /usr/java/jdk1.7.0_45 did not work for me

I spend quite some time to tackle similar error. It looks like package manager might create mess in Java installations. Path to Java is sometimes hardcoded in bash files. I found one in /etc/profile.d/jdk.sh. It just overrides your settings. Another fix/workaround for that is to update symlink, in my case it was /usr/lib/jvm/java ⇒ /usr/java/jdk1.7.0_45. Try to look for java/bin text in all bash files.

in super user privilege on your terminal open
vi etc/environment
on opened file add JAVA_HOME path
JAVA_HOME="/usr/lib/jvm/java-7-openjdk-i386/"
Hope you set the JAVA_HOME
check if your JAVA_HOME is set using command
echo $JAVA_HOME

I used OpenJDK as default java , updated JAVA_HOME in /etc/environment and all the issues went. Thanks for all your effort helping me through this

I had the same problem. My workaround was:
cd /usr/lib/jvm/java-8-oracle/jre/bin
sudo ln -s /usr/lib/jvm/java-8-oracle/bin/java java

Related

Setting Java version for maven build

I am trying to set the java version for a maven build when I execute it from a shell script. Fot some reason it is not picking up the intended java version. Any advise welcome.
I am running on a linux centos 7 os.
I have downloaded java 14 from https://jdk.java.net/14/ (Linux / x64), and extracted it to:
/usr/lib/jvm/jdk-14.0.2
pom.xml
<properties>
<java.version>14</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<maven.compiler.release>${java.version}</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jsk.version>2.2.3</jsk.version>
<start-class>com.nexct.approvalservice.NexctApprovalServiceApplication</start-class>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<fork>true</fork>
</configuration>
</plugin>
deploy.sh
export JAVA_HOME=/usr/lib/jvm/jdk-14.0.2
export PATH=$JAVA_HOME/bin:$PATH
echo $JAVA_HOME
echo | java -version
echo "maven build ..."
mvn clean install -V -DskipTests -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2
output:
/usr/lib/jvm/jdk-14.0.2
openjdk version "14.0.2" 2020-07-14
OpenJDK Runtime Environment (build 14.0.2+12-46)
OpenJDK 64-Bit Server VM (build 14.0.2+12-46, mixed mode, sharing)
maven build ...
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: /opt/apache-maven-3.6.3
Java version: 1.7.0_161, vendor: Oracle Corporation, runtime: /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.161-2.6.12.0.el7_4.x86_64/jre
Default locale: en_US, platform encoding: ANSI_X3.4-1968
OS name: "linux", version: "3.10.0-957.21.3.el7.x86_64", arch: "amd64", family: "unix"
[INFO] BUILD FAILURE
Compilation failure
[ERROR] javac: invalid flag: -parameters
[ERROR] Usage: javac <options> <source files>
[ERROR] use -help for a list of possible options
I found a solution:
If I set, this it works. Maven compiles the code.
<executable>/usr/lib/jvm/jdk-14.0.2/bin/javac</executable>
However, this is not ideal because the path to the install is hard-coded, so on other servers with a different JAVA_HOME location, it won't work. Is it possible to reference $JAVA_HOME from within the POM file? and do something like this?
<executable><$JAVA_HOME>/bin/javac</executable>
e.g.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>${java.version}</release>
<source>${java.version}</source>
<target>${java.version}</target>
<compilerVersion>${java.version}</compilerVersion>
<fork>true</fork>
<executable>/usr/lib/jvm/jdk-14.0.2/bin/javac</executable>
</configuration>
</plugin>

How can I change my system Library from jre to jdk in java Maven [duplicate]

I am trying to build a Hudson plugin I've modified and it requires jdk1.6. This is fine, but I don't see how I can tell maven where the different jdk is. I've found few mentions on the internet but they don't seem to apply to me. Some suggest adding some config to .m2/settings.xml but I don't have a settings.xml. Plus, I don't want to use 1.6 for all maven builds.
One kink is I am using mvn in cygwin, if that matters at all. It appears I should be able to make the specification in the project pom file, but the existing pom is pretty bare.
So bottom line is, is there a way to specify a jdk for a single invocation of maven?
So bottom line is, is there a way to specify a jdk for a single invocation of maven?
Temporarily change the value of your JAVA_HOME environment variable.
Seems that maven now gives a solution here : Compiling Sources Using A Different JDK
Let's say your JAVA_HOME points to JDK7 (which will run maven processes)
Your pom.xml could be :
<build>
<plugins>
<!-- we want JDK 1.6 source and binary compatiblility -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<!-- ... -->
<!-- we want sources to be processed by a specific 1.6 javac -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<verbose>true</verbose>
<fork>true</fork>
<executable>${JAVA_1_6_HOME}/bin/javac</executable>
<compilerVersion>1.3</compilerVersion>
</configuration>
</plugin>
</plugins>
</build>
If your developpers just add (and customize) the following lines in their settings.xml, your pom will be platform independant :
<settings>
[...]
<profiles>
[...]
<profile>
<id>compiler</id>
<properties>
<JAVA_1_4_HOME>C:\Program Files\Java\j2sdk1.4.2_09</JAVA_1_4_HOME>
<JAVA_1_6_HOME>C:\Program Files\Java\j2sdk1.6.0_18</JAVA_1_6_HOME>
</properties>
</profile>
</profiles>
[...]
<activeProfiles>
<activeProfile>compiler</activeProfile>
</activeProfiles>
</settings>
compile:compile has a user property that allows you to specify a path to the javac.
Note that this user property only works when fork is true which is false by default.
$ mvn -Dmaven.compiler.fork=true -Dmaven.compiler.executable=/path/to/the/javac compile
You might have to double quote the value if it contains spaces.
> mvn -Dmaven.compiler.fork=true -Dmaven.compiler.executable="C:\...\javac" compile
See also Maven custom properties precedence.
As u said "Plus, I don't want to use 1.6 for all maven builds."....So better I will say modify your pom file and specify which jdk version to use.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.9</source>
<target>1.9</target>
</configuration>
</plugin>
</plugins>
</build>
It will ensure that your particular project uses that version of jdk.
I say you setup the JAVA_HOME environment variable like Pascal is saying:
In Cygwin if you use bash as your shell should be:
export JAVA_HOME=/cygdrive/c/pathtothejdk
It never harms to also prepend the java bin directory path to the PATH environment variable with:
export PATH=${JAVA_HOME}/bin:${PATH}
Also add maven-enforce-plugin to make sure the right JDK is used. This is a good practice for your pom.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>enforce-versions</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireJavaVersion>
<version>1.6</version>
</requireJavaVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Please, see Maven Enforcer plugin – Usage.
If you have installed Java through brew in Mac then chances are you will find your Java Home Directory here:
/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home
The next step now would be to find which Java Home directory maven is pointing to. To find it type in the command:
mvn -version
The fields we are interested in here is:
Java version and runtime.
Maven is currently pointing to Java 13. Also, you can see the Java Home path under the key runtime, which is:
/usr/local/Cellar/openjdk/13.0.2+8_2/libexec/openjdk.jdk/Contents/Home
To change the Java version of the maven, we need to add the Java 8 home path to the JAVA_HOME env variable.
To do that we need to run the command:
export JAVA_HOME=/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home
in the terminal.
Now if we check the maven version, we can see that it is pointing to Java 8 now.
The problem with this is if you check the maven version again in the new terminal, you will find that it is pointing to the Java 13. To avoid this I would suggest adding the JAVA_HOME variable in the ~/.profile file.
This way whenever your terminal is loading it will take up the value you defined in the JAVA_HOME by default. This is the line you need to add in the ~/.profile file:
export JAVA_HOME=/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home
You can open up a new terminal and check the Maven version, (mvn -version) and you will find it is pointing to the Java 8 this time.
I know its an old thread. But I was having some issues with something similar to this in Maven for Java 8 compiler source. I figured this out with a quick fix mentioned in this article thought I can put it here and maybe can help others:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
Maven uses variable $JAVACMD as the final java command, set it to where the java executable is will switch maven to different JDK.
You could also set the JDK for Maven in a file in your home directory ~/.mavenrc:
JAVA_HOME='/Library/Java/JavaVirtualMachines/jdk-11.0.5.jdk/Contents/Home'
This environment variable will be checked by the mvn script and used when present:
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
https://github.com/CodeFX-org/mvn-java-9/tree/master/mavenrc
Hudson also allows you to define several Java runtimes, and let you invoke Maven with one of these. Have a closer look on the configuration page.
Yet another alternative to manage multiple jdk versions is jEnv
After installation, you can simply change java version "locally" i.e. for a specific project directory by:
jenv local 1.6
This will also make mvn use that version locally, when you enable the mvn plugin:
jenv enable-plugin maven
I update my ~/.m2/settings.xml
<settings>
<profiles>
<profile>
<id>j8</id>
<profile>
<id>j8</id>
<properties>
<maven.compiler.fork>true</maven.compiler.fork>
<maven.compiler.executable>${env.JAVA_HOME8}/bin/javac.exe</maven.compiler.executable>
</properties>
</profile>
<profile>
<id>j11</id>
<properties>
<maven.compiler.fork>true</maven.compiler.fork>
<maven.compiler.executable>${env.JAVA_HOME11}/bin/javac.exe</maven.compiler.executable>
</properties>
</profile>
</profiles>
<settings>
For build with Java8 I run mvn with properties:
mvn compile -Pj8
and for Java 11
mvn compile -Pj11
If nothing else works and even after you set JAVA_HOME to a correct path, check if there is no override of the JAVA_HOME path in <user>/.mavenrc!
As a further tip, the mvn file is a bash script (on Linux).. so if necessary you can inspect the source [and change it].
I had build problem with maven within Eclipse on Windows 7.
Though I observed mvn build was running just fine from command line.
mvn -T 5 -B -e -X -U -P test clean install -Dmaven.surefire.debug --settings ..\..\infra-scripts\maven-conf\settings.xml > output.log
Eclipse was considering as default JVM a JRE installation instead of JDK so it was failing on compilation.
I added to eclipse.ini following line:
-vm
C:\Program Files (x86)\Java\jdk1.8.0_25\bin
Also when starting from eclipse I used in "Goals" section following list:
-T 5 -B -e -X -U -P test clean install -Dmaven.surefire.debug --settings ..\..\infra-scripts\maven-conf\settings.xml
Compilation error got solved.
For Java 9 :
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>9</source>
<target>9</target>
</configuration>
</plugin>
</plugins>
</build>

Maven Java compiler - compilation error using wrong compliance version

When Running install from Eclipse we have no issues as the compiler version is set to 1.8.
When running mvn install in terminal we get the following error.
ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project servicehelper: Compilation failure
[ERROR] try-with-resources is not supported in -source 1.5
[ERROR] (use -source 7 or higher to enable try-with-resources)
[ERROR]
When using mvn install -X we're seeing -target 1.5
However here are my java and javac versions
mvn -version
Apache Maven 3.5.0 (ff8f5e7444045639af65f6095c62210b5713f426; 2017-04-03T14:39:06-05:00)
Maven home: /usr/local/Cellar/maven/3.5.0/libexec
Java version: 1.8.0_131, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "mac os x", version: "10.12.5", arch: "x86_64", family: "mac"
java -version
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
javac -version
javac 1.8.0_131
I seems like from every version i run that we should have 1.8 compliance but maven target continues to try and install with 1.5 compliance.
Add this plugin to your pom.xml file.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<compilerVersion>1.8</compilerVersion>
</configuration>
</plugin>
The way to go is first to define the version of the used plugin which means:
<project>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
You should always pin plugin versions which means all used plugin in your build.
The other option to define the java version (source/target) can be done via:
<project>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
Or you can omit the pluginManagement if you have already pinned the plugin version via a corporate pom parent and only give the above properties.
If you have to run Maven with another JDK than you need to compile/test your code you need to go via toolchains
Or you can define the compiler to use via fork option which means to hard code the location of your JDK in your pom file which is not a good idea.
You can try adding the tag java.version on your pom.xml
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>

setting JAVA_HOME for Maven ONLY regardless of my code java

I am running different java projects. Understanding that changing java_home system environment each time I switch between them is a bad idea, I'm starting to set JAVA_HOME specifically for each one of them independently.
When I set JAVA_HOME for maven (version 2) runtime (the java maven uses to run, being a java application)?
To my understanding, JAVA_HOME for maven should not affect how my code is compiled and run (which are supposed to be configured using maven-compiler-plugin source and target). Right?
When I set JAVA_HOME in mvn.bat:
#REM Maven2 Start Up Batch script
set JAVA_HOME=C:\dev\tools\jdk-1.6
And my maven-compiler-plugin is configured this way:
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
I receive this error:
[ERROR] BUILD ERROR
[INFO] --------------------------------------
[INFO] Fatal error compiling
Embedded error: invalid target release: 1.7
Why does JAVA_HOME specified for maven runtime affect my code compilation? How to separate between the two?
Maven will use the JRE specified in JAVA_HOME
By default it will use the JDK from the same folder for compiling .java files
However you can change it in maven-compile-plugin configuration
<project>
[...]
<build>
[...]
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<verbose>true</verbose>
<fork>true</fork>
<executable><!-- path-to-javac --></executable>
<compilerVersion>1.3</compilerVersion>
</configuration>
</plugin>
</plugins>
[...]
</build>
[...]
</project>

Maven - invalid target release 1.7 with Java 1.7

Everything seems correct, but it just won't work.
$ sudo mvn clean package
...
[INFO] Compilation failure
Failure executing javac, but could not parse the error:
javac: invalid target release: 1.7
Versions :
$ mvn -v
Apache Maven 2.2.1 (r801777; 2009-08-06 20:16:01+0100)
Java version: 1.7.0_75
Java home: /Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre
$ java -version
java version "1.7.0_75"
Java(TM) SE Runtime Environment (build 1.7.0_75-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.75-b04, mixed mode)
$ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/
pom.xml :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
For the record :
$ /usr/libexec/java_home
/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home
But I don't think this is the problem.
Any ideas ?
Try updating compiler plugin. Version 3.3 is the latest. If that does not help try using Maven 3+
You have to set the configuration for maven-compiler-plugin like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
Best is to configure this within a pluginManagement area.
mvn clean removes target folder which is read only.
Solution : Use sudo right ? Except that sudo no longer reads your variables or PATH but those of super user
sudo mvn -v now shows Java 1.6
Big thanks to khmarbaise

Categories

Resources