Let's say you create a new project, and want it to make use of some 3rd party library, say, widget.jar. Where do you add this JAR:
File >> Project Properties >> Libraries >> Compile-Time Libraries; or
File >> Project Properties >> Libraries >> Run-Time Libraries; or
Tools >> Libraries (Library Manager) >> Library Classpath; or
Tools >> Java Platforms (Java Platform Manager)
All of these dialogs seem to do the same thing but I'm sure they all have their proper usages. Can't find a good "best practices" article online and the NetBeans Help Contents dialog isn't helping with this either.
Right click 'libraries' in the project list, then click add.
You want to add libraries to your project and in doing so you have two options as you yourself identified:
Compile-time libraries are libraries which is needed to compile your application. They are not included when your application is assembled (e.g., into a war-file). Libraries of this kind must be provided by the container running your project.
This is useful in situation when
you want to vary API and implementation, or when the library is supplied by the container (which is typically the case with javax.servlet which is required to compile but provided by the application server, e.g., Apache Tomcat).
Run-time libraries are libraries which is needed both for compilation and when running your project. This is probably what you want in most cases. If for instance your project is packaged into a war/ear, then these libraries will be included in the package.
As for the other alernatives you have either global libraries using Library Manageror jdk libraries. The latter is simply your regular java libraries, while the former is just a way for your to store a set of libraries under a common name. For all your future projects, instead of manually assigning the libraries you can simply select to import them from your Library Manager.
If your project's source code has import statements that reference classes that are in widget.jar, you should add the jar to your projects Compile-time Libraries. (The jar widget.jar will automatically be added to your project's Run-time Libraries). That corresponds to (1).
If your source code has imports for classes in some other jar and the source code for those classes has import statements that reference classes in widget.jar, you should add widget.jar to the Run-time libraries list. That corresponds to (2).
You can add the jars directly to the Libraries list in the project properties. You can also create a Library that contains the jar file and then include that Library in the Compile-time or Run-time Libraries list.
If you create a NetBeans Library for widget.jar, you can also associate source code for the jar's content and Javadoc for the APIs defined in widget.jar. This additional information about widget.jar will be used by NetBeans as you debug code. It will also be used to provide addition information when you use code completion in the editor.
You should avoid using Tools >> Java Platform to add a jar to a project. That dialog allows you to modify the classpath that is used to compile and run all projects that use the Java Platform that you create. That may be useful at times but hides your project's dependency on widget.jar almost completely.
Project Files Services Tabls
go files tabs
drag drop file to libs files hover.
return project tabs and what are you see :)
Related
I have a Java project in Eclipse that uses javax.xml.bind.JAXB classes.
Starting the application from inside Eclipse works perfectly.
However, when I export the project as (runnable) jar file and run it using java -jar myfile.jar it terminates with a java.lang.NoClassDefFoundError: javax/xml/bin/JAXBException.
Also playing around with the three options for Library handling in Eclipse Runnable JAR File Specification (extract, package, sub-folder) does not solve the problem - in fact, no libraries are exported in any case.
It seems that the library for JAXB (it seems to be rt.jar) is not considered as required library to be included into the jar file. However, when running the jar file, it is not found nevertheless.
I have read that the library must be added to the classpath but this seems strange to me as rt.jar is part of the standard libraries. Is there something special about this library?
Currently, I do not use Maven or something similar for dependency and build management and if possible I want to avoid it for the future. I think, there also must be a way without Maven.
I found several posts here on SO and in Google but was not able to work out a solution for me.
Thank you very much!
As remarked in the comments, Eclipse probably uses a different Java version than your system (by default). The JAXB API and implementation is not available in JRE 11.
To work on all versions of Java, your best option is:
Download the JAXB RI distribution. Nowadays I'll choose version 3.0 (which is binary incompatible with the one in Java 8, since it uses jakarta.xml instead of javax.xml for the packages name) as in Juliano's answer:
https://repo1.maven.org/maven2/com/sun/xml/bind/jaxb-ri/3.0.0/jaxb-ri-3.0.0.zip
Copy the 4 files jakarta.activation.jar, jakarta.xml.bind-api.jar, jaxb-core.jar and jaxb-impl.jar from the mod folder into the library folder of your project (let's say lib),
Add the 4 libraries to the project's "Build Path",
Make sure you use JAXB 3.0 throughout your code (the packages of the annotations and classes start with jakarta.xml)
Run the application once in Eclipse, so it updates the Run Configuration (or update the classpath of the Run Configuration yourself),
Export the project to a JAR file.
Among the three export options proposed by Eclipse: "extract required libraries" will create a so-called fat jar (everything in one JAR-file). It works, but it deletes the licence notices in the JAXB jars (so it can not be distributed). "copy required libraries" is your best option, but then you have to move the jar file together with the subfolder. _". "package required libraries" will not work, since jars in a jar are not read by the JVM (unlike JARs in a WAR package).
Edit by the author of the question:
The above worked for me well except that I experienced small differences how the two libraries (javax.xml in Java 8 and jakarta.xml in version 3.0) handle #XmlAttribute annotations. In javax.xml, I could place an annotation without further arguments on the public getter-method, e.g.
#XmlAttribute
public String getDescription() {
return "";
}
And this worked when the attribute name in the xml file is description. However, with jakarta.xml I had to add the name of the attribute:
#XmlAttribute(name="description")
public String getDescription() {
return "";
}
Just in the case, that others experience the same problem.
I thought about this myself too, since I am new to java.
There is a description of a Extension Mechanism in the java tutorials (SE), but it is no longer used since deprecated by Oracle. See, just to know of what I am talking about: https://docs.oracle.com/javase/tutorial/ext/index.html
What was this Extension thing in a nutshell: just drop your jar files inside the jdk lib and you could use the import keyword in all your classes to use the new jar file.
However, others had to do the same thing in their computers to run a class which imported your own update to the jdk.
Maven do something like the above. It searches on the pom file which other jar files it should include in your jar when you build an application. Hence, it may run anywhere.
Another way of looking into this is the answer which you should try to do.
A clunckier way of doing what Maven does without its pom structure is to create a new folder inside your src folder and copy the jakarta.xml.bind-api.jar. Just like when you create an object (aJavaBean) and need to use it in another class.
The file you need to include in your library is available at:
https://repo1.maven.org/maven2/com/sun/xml/bind/jaxb-ri/3.0.0/jaxb-ri-3.0.0.zip
Finally, extract the classes inside this newly created folder and use the import keyword in the classes that depend on it just like when you create your own classes.
Another thing you should try is to use the manifest file when making your jar.
https://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html
This tutorial shows how to include a classpath to the files you need to run as a dependency. Make sure that everything you need is inside the newly created jar file.
Also, set the entry point in the manifest, so your application can run just using
java -jar MyJar.jar
in the command line.
The easiest way is to use JDK 8 (or older JDK) that has embedded the required jaxb library. The hard way requires that you set your CLASSPATH variable pointing to each required jaxb jar file.
From spec at https://javaee.github.io/jaxb-v2/doc/user-guide/release-documentation.html#a-2-3-0, the following jars are required using a java version 11 or above.
jaxb-api.jar
jaxb-core.jar
jaxb-impl.jar
A good article on this question is https://www.jesperdj.com/2018/09/30/jaxb-on-java-9-10-11-and-beyond/
I have a utilities file named utilities.java that is located in my ...\NetbeansProjects\Utilities folder and I want to use the methods in it in any java project that I work on.
If I right-click Libraries folder, there is an option to include JAR/folder... so I select that and find and select the Utilities folder and Absolute Path to it as shown, which adds the Utilities folder to the Libraries folder, as shown.
But how do I reference the methods that are in Utilities.java?
import doesn't offer any help and all I get on every attempted reference is Cannot find symbol.
I can't turn Utilities.java into a .jar file (can I??) because the option to Compile is grayed out.
What do I prefix to each such unresolved external reference to successfully link such methods to my code?
Whether I try to just import or import static, I get error, with suggestions to change to some inappropriate import.
What's irritating is that I think I've successfully done this before....
Based on your screenshot, it looks like you are using an older version of NetBeans (perhaps v8.2 or similar). I will assume this - but it would be worth upgrading if possible.
Generally, I would recommend creating two NetBeans projects, and then include the utilities project as a dependency in the application project.
You can use the "Library" features of NetBeans (as shown in your screenshot) but I think it is cleaner to just create projects, which can then be managed by Git/Mercurial/etc. as needed, as separate projects, with no need to rely on NetBeans-specific library management features.
Ant-Based Approach
For an Ant-based approach (the default for NetBeans 8), that would be something like this:
The above was created as follows:
Create the utilities project:
File > New Project > Java > Java Class Library
Project Name: MyUtilities
Create your package and your Utilities.java file. Add the code you need.
Clean and build the project.
Create a project to use the utility JAR:
File > New Project > Java > Java Application
Project Name: MyApplication
Right-click on MyApplication in the project explorer and select the Properties pop-up window.
Libraries > Add Project - find the MyUtilities project and select it, click on "Add Project JAR Files".
Now you will see that project's jar file listed as one of MyApplication's library dependencies.
After cleaning and building the project you will see a file structure as follows:
Note: For NetBeans 12, it's similar, except they now make the choice of an Ant project (vs. Maven, Gradle) explicit, rather than the default.
Maven-Based Approach
It's a similar approach: Two separate projects. In this case they are both "Maven > Java Application" projects - there is no distinction, in contrast to the Ant approach.
The main difference is how you include the utilities JAR in your applications. that depends on how you want to manage your Maven artifacts - and is a bit outside the scope of this question. One way is to follow the guidelines here - but I think there are other approaches, also.
Let's say you create a new project, and want it to make use of some 3rd party library, say, widget.jar. Where do you add this JAR:
File >> Project Properties >> Libraries >> Compile-Time Libraries; or
File >> Project Properties >> Libraries >> Run-Time Libraries; or
Tools >> Libraries (Library Manager) >> Library Classpath; or
Tools >> Java Platforms (Java Platform Manager)
All of these dialogs seem to do the same thing but I'm sure they all have their proper usages. Can't find a good "best practices" article online and the NetBeans Help Contents dialog isn't helping with this either.
Right click 'libraries' in the project list, then click add.
You want to add libraries to your project and in doing so you have two options as you yourself identified:
Compile-time libraries are libraries which is needed to compile your application. They are not included when your application is assembled (e.g., into a war-file). Libraries of this kind must be provided by the container running your project.
This is useful in situation when
you want to vary API and implementation, or when the library is supplied by the container (which is typically the case with javax.servlet which is required to compile but provided by the application server, e.g., Apache Tomcat).
Run-time libraries are libraries which is needed both for compilation and when running your project. This is probably what you want in most cases. If for instance your project is packaged into a war/ear, then these libraries will be included in the package.
As for the other alernatives you have either global libraries using Library Manageror jdk libraries. The latter is simply your regular java libraries, while the former is just a way for your to store a set of libraries under a common name. For all your future projects, instead of manually assigning the libraries you can simply select to import them from your Library Manager.
If your project's source code has import statements that reference classes that are in widget.jar, you should add the jar to your projects Compile-time Libraries. (The jar widget.jar will automatically be added to your project's Run-time Libraries). That corresponds to (1).
If your source code has imports for classes in some other jar and the source code for those classes has import statements that reference classes in widget.jar, you should add widget.jar to the Run-time libraries list. That corresponds to (2).
You can add the jars directly to the Libraries list in the project properties. You can also create a Library that contains the jar file and then include that Library in the Compile-time or Run-time Libraries list.
If you create a NetBeans Library for widget.jar, you can also associate source code for the jar's content and Javadoc for the APIs defined in widget.jar. This additional information about widget.jar will be used by NetBeans as you debug code. It will also be used to provide addition information when you use code completion in the editor.
You should avoid using Tools >> Java Platform to add a jar to a project. That dialog allows you to modify the classpath that is used to compile and run all projects that use the Java Platform that you create. That may be useful at times but hides your project's dependency on widget.jar almost completely.
Project Files Services Tabls
go files tabs
drag drop file to libs files hover.
return project tabs and what are you see :)
I had a question that was answered with adding jfxrt.jar to standard Eclipse build path.
I followed the suggestion, adding the jfxft.jar as an External Jar on the jdk1.7.0_10.jdk JRE i have installed (under Eclipse > Preferences > Java > Installed JREs).
But when I import "javafx.application.Application"
It errors with:
Access Restriction: The type Application is not accessible due to restriction on required library /Library/Java/JavaVirtualMachines/jdk1.7.0_10.jdk/Contents/Home/jre/lib/jfxrt.jar
There are posts on this such as Access restriction: Is not accessible due to restriction on required library ..\jre\lib\rt.jar
I can fix this possibly by the suggestions in that thread (though I'm not convinced they are good solutions).
Or I found a better solution of adding the External Jar directly to the project:
- go to the JRE and remove the External Jar as setup above
- Open project properties and go to Java Build Path
- Go to Libraries tab
- Add External JARS... and choose exactly the same jfxrt.jar
No access restrictions now!
Why does it work one way but not the other? The advantage of adding directly to the JRE configuration is that it only needs to be done once.
Thanks,
Hank
I would not recommend adding JARs to the JRE configuration like that, it's just too easy to forget they are there and that can lead to confusing behavior if you don't expect that particular JAR to be on the build path for a particular project. Also, what happens if one project wants to use a different version of the library?
There are at least 2 other options that I would consider:
Define a User Library for JavaFX and then include the User Library on the projects that need it. You still would have to add the User Library to each project that needs it, but that's not such a big deal IMO, as it only has to be done once for each project.
Create a separate project to contain the JAR(s), call it something like "JavaFX Libs." Add the JARs to its build path and make sure to export them on the Order and Export tab; then add "JavaFx Libs" project as a dependency for whatever projects need it.
I saw that in Eclipse I can define User Libraries - to make setting the classpath easier (and probably for other reasons as well).
The problem is, that these libraries are only available in the workspace, and if I want other people using the same project to use them - I need to export my user library and they need to import it.
Is there any functionality like this on the project level? I basically need to have a 'classpath group' - can it be done?
If not, is there an automatic way to auto import the user library to the workspace when importing the project?
I'm using Eclipse 3.6.
JDT has the 2 concepts, user libraries and classpath variables. In the classpath variable, you can add jars to your project. Other team members have to fill in the variables in their workspace so their classpath is complete. This is useful when external jars might be in different locations on each team members local file system.
The USER_LIBRARY is a container for adding a logical group of local jars all at once. For example, the JRE_LIB container represents a number of local jars. But as you've seen, it points to a local set of jars meant to be used in multiple projects (as the JRE is added to multiple projects).
Aside from export/import (which you're already doing), I don't believe you can check CLASS_LIBRARIES into a project's SCM. If there was, the preference page would have a "Configure Project specific settings" link at the top.
Your best bet is to simply add the jars to the project, so they'll be included in the SCM. If they can be in different locations depending on the rest of your team, then use a classpath variable so it can be set in each workspace. That's the least amount of hassle as far as team members checking out the project and being ready to go.
The best way IMO is to use m2eclipse - Maven plugin for eclipse. In Maven all the dependencies are defined in pom.xml and downloaded automatically as needed. This means that the only thing you share with your team is pom.xml - your project definition.
There is a lot more advantages when using m2eclipse vs standard eclipse approch. More information is at http://www.sonatype.com/books/m2eclipse-book/reference/
The way I have used user libraries is for something like Ant. Define a user library "ant" for all the jars in ANT_HOME/lib. If including this in your Eclipse .classpath and then sharing with other users, they will get a build problem report until they create that "ant" user library themselves. It's useful, but you need to share knowledge on how to create the library. If you're using it for simple cases like above, then instructions for adding the right jars to the library are straightforward.
Another approach I've used is to build classpaths pointing into a folder (or folders) defined as a variable in Eclipse. See File -> New Folder -> Advanced -> Link to folder in the file system -> Variables. This lets you setup (again at workspace level) variable references to one or more folders. You can then build your Eclipse classpath/s with reference to the folder/s.
So say in your development environment, everyone needs to have a directory called "thirdparty" containing all the external jars dependencies (probably in hierarchy within that dir: thirdparty/apache; thirdparty/sun; ...). You define "thirdparty" as a variable pointing to wherever that dir is on your current system, you create a folder in your project/s using the variable. You can then setup (and share) classpath using paths into that folder.
It's similar to User Library and with similar limitations. The limitation is that the other users you share your project with must create variable folder/s as you have. But it's more flexible in that they don't have to add the jars explicitly as they do with a library; rather, your classpath/s in Eclipse point into the folder, as required for each project.
Note that although the folder variable is defined at workspace level, it can be reused in multiple projects, each of which builds their classpaths (.classpath files) with different references into the folder).
This is maybe something easier to show than to describe with words, but I hope it makes sense.