// 
//     Licensed to the Apache Software Foundation (ASF) under one
//     or more contributor license agreements.  See the NOTICE file
//     distributed with this work for additional information
//     regarding copyright ownership.  The ASF licenses this file
//     to you under the Apache License, Version 2.0 (the
//     "License"); you may not use this file except in compliance
//     with the License.  You may obtain a copy of the License at
// 
//       http://www.apache.org/licenses/LICENSE-2.0
// 
//     Unless required by applicable law or agreed to in writing,
//     software distributed under the License is distributed on an
//     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
//     KIND, either express or implied.  See the License for the
//     specific language governing permissions and limitations
//     under the License.
//

= DevFaqNetBeansFullHack
:jbake-type: wiki
:jbake-tags: wiki, devfaq, needsreview
:jbake-status: published
:keywords: Apache NetBeans wiki DevFaqNetBeansFullHack
:description: Apache NetBeans wiki DevFaqNetBeansFullHack
:toc: left
:toc-title:
:syntax: true

== Can I test changes to the IDE without going through the license check and so on?

If you set the system property `netbeans.full.hack` to `true`,
the following IDE behaviors will be disabled
to make it quicker or more reliable to test other functionality:

* Auto Update background check (to see if updates are available); you can still use AU via *Tools > Plugin Manager*
* prompting about still-running tasks when shutting down
* license dialog
* import of old user directory
* IDE registration dialog
* dialog suggesting that you submit usage statistics
* welcome screen displayed by default and RSS feed refreshed
* blocking dialog when some modules could not be loaded
* use of `~/NetBeansProjects/` for newly created projects (`java.io.tmpdir` will be used instead)
* resizing gesture submit dialog (`SubmitStatus.resize`)
* weekly Maven repository indexing (can be configured in Options dialog)
* long package name for default group ID in new Maven project (`test` used instead)

This property is set by default when you:

* run the IDE from sources using `ant tryme`
* run the IDE from a netbeans.org module project using *Run Project* (`ant run`)
* run a functional test using `NbModuleSuite` or a unit test using `NbTestCase`

If you need to test one of the suppressed behaviors
(e.g. you are working on the license dialog),
just do not set this property.
For the `ant tryme` and `ant run` cases, add

[source,java]
----

tryme.args=
----

to `nbbuild/user.build.properties` or `~/.nbbuild.properties`.

== Apache Migration Information

The content in this page was kindly donated by Oracle Corp. to the
Apache Software Foundation.

This page was exported from link:http://wiki.netbeans.org/DevFaqNetBeansFullHack[http://wiki.netbeans.org/DevFaqNetBeansFullHack] , 
that was last modified by NetBeans user Lfischmeistr 
on 2013-11-25T13:00:42Z.


*NOTE:* This document was automatically converted to the AsciiDoc format on 2018-02-07, and needs to be reviewed.
